bansi1.inc 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. {$APPTYPE CONSOLE}
  2. {$ifdef fpc}
  3. {$Mode Objfpc}
  4. {$endif}
  5. {$H+}
  6. uses
  7. {$ifdef NEXUS}
  8. nxReplacementMemoryManager,
  9. {$endif}
  10. {$if defined(UNIX) and defined(THREAD)}
  11. cthreads,
  12. {$ifend}
  13. sysutils,
  14. classes;
  15. const
  16. BenchCount = 1;
  17. cTimes = 1000000;
  18. Number1: array [0..19] of string = (
  19. 'zero', 'one', 'two', 'three', 'four', 'five',
  20. 'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
  21. 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen',
  22. 'seventeen', 'eighteen', 'nineteen');
  23. Number9: array [0..9] of string = (
  24. '', ' one', ' two', ' three', ' four', ' five',
  25. ' six', ' seven', ' eight', ' nine');
  26. Number10: array [0..9] of string = (
  27. 'zero', 'ten', 'twenty', 'thirty', 'fourty', 'fifty',
  28. 'sixty', 'seventy', 'eighty', 'ninety');
  29. function GetTickCount : Cardinal;
  30. var
  31. h,m,s,s1000 : word;
  32. begin
  33. decodetime(time,h,m,s,s1000);
  34. result:=h*3600000+m*60000+s*1000+s1000;
  35. end;
  36. procedure StartLog(var StartTick: Cardinal);
  37. begin
  38. StartTick:= GetTickCount;
  39. end;
  40. procedure EndLog(const Text: string; StartTick: Cardinal; Count: Integer);
  41. begin
  42. writeln(Text, ': ', Count, ' done in ', (GetTickCount - StartTick) / 1000.0: 0: 3, ' sec');
  43. end;
  44. type
  45. TFastStringRec = record
  46. l: Cardinal;
  47. s: string;
  48. end;
  49. procedure FS_Clear(var AFS: TFastStringRec); {$ifdef FPC}inline;{$endif}
  50. begin
  51. AFS.L:= 0;
  52. AFS.S:= '';
  53. end;
  54. procedure FS_Assign(var AFS: TFastStringRec; const s: string); {$ifdef FPC}inline;{$endif}
  55. begin
  56. AFS.l:= Length(s);
  57. SetLength(AFS.s, (AFS.l and not 63) + 64);
  58. if AFS.l > 0 then
  59. Move(s[1], AFS.s[1], AFS.l);
  60. end;
  61. procedure FS_Append(var AFS: TFastStringRec; const s: string); overload;
  62. {$ifdef FPC}inline;{$endif}
  63. var
  64. L, ls: Cardinal;
  65. begin
  66. ls:= Length(s);
  67. if ls > 0 then begin
  68. L:= AFS.l;
  69. AFS.l:= L + ls;
  70. SetLength(AFS.s, (AFS.l and not 63) + 64);
  71. Move(s[1], AFS.s[1 + L], ls);
  72. end;
  73. end;
  74. procedure FS_Append(var AFS, S: TFastStringRec); overload; {$ifdef FPC}inline;{$endif}
  75. var
  76. L: Cardinal;
  77. begin
  78. if S.L > 0 then begin
  79. L:= AFS.l;
  80. AFS.l:= L + S.L;
  81. SetLength(AFS.s, (AFS.l and not 63) + 64);
  82. Move(S.S[1], AFS.S[1 + L], S.L);
  83. end;
  84. end;
  85. function FS_ToStr(var AFS: TFastStringRec): string; {$ifdef FPC}inline;{$endif}
  86. begin
  87. if AFS.L > 0 then begin
  88. SetLength(Result, AFS.L);
  89. Move(AFS.S[1], Result[1], AFS.L);
  90. end else
  91. Result:= '';
  92. end;
  93. procedure NumberToText_V1(out s: string; n: Integer);
  94. procedure TensToText(var s: TFastStringRec; dig: Integer);
  95. var
  96. x: Integer;
  97. begin
  98. if dig > 0 then begin
  99. if dig >= 20 then begin
  100. x:= dig mod 10;
  101. FS_Assign(s, Number10[dig div 10]);
  102. if x <> 0 then
  103. FS_Append(s, Number9[x]);
  104. end else begin
  105. FS_Assign(s, Number1[dig]);
  106. end;
  107. end else
  108. FS_Clear(s);
  109. end;
  110. procedure HundredsToText(var s: TFastStringRec; dig: Integer);
  111. var
  112. h, t: Integer;
  113. s1: TFastStringRec;
  114. begin
  115. if dig > 0 then begin
  116. t:= dig mod 100;
  117. h:= dig div 100;
  118. if h > 0 then begin
  119. TensToText(s, h);
  120. if t > 0 then begin
  121. FS_Append(s, ' houndred ');
  122. TensToText(s1, t);
  123. FS_Append(s, s1);
  124. end else
  125. FS_Append(s, ' houndred');
  126. end else
  127. TensToText(s, t);
  128. end else
  129. FS_Clear(s);
  130. end;
  131. var
  132. dig, h: Integer;
  133. s0, s1: TFastStringRec;
  134. begin
  135. if n > 0 then begin
  136. dig:= n div 1000;
  137. h:= n mod 1000;
  138. if dig > 0 then begin
  139. HundredsToText(s0, dig);
  140. if h > 0 then begin
  141. FS_Append(s0, ' thousand ');
  142. HundredsToText(s1, h);
  143. FS_Append(s0, s1);
  144. end else
  145. FS_Append(s0, ' thousand');
  146. end else
  147. HundredsToText(s0, h);
  148. s:= FS_ToStr(s0);
  149. end else
  150. s:= Number1[0];
  151. end;
  152. procedure NumberToText_V2(out s: string; n: Integer);
  153. procedure TensToText(out s: string; dig: Integer);
  154. var
  155. x: Integer;
  156. begin
  157. if dig > 0 then begin
  158. if dig >= 20 then begin
  159. x:= dig mod 10;
  160. if x <> 0 then begin
  161. s:= Number10[dig div 10] + Number9[x]
  162. end else
  163. s:= Number10[dig div 10];
  164. end else begin
  165. s:= Number1[dig];
  166. end;
  167. end else
  168. s:= '';
  169. end;
  170. procedure HundredsToText(out s: string; dig: Integer);
  171. var
  172. h, t: Integer;
  173. s1: string;
  174. begin
  175. if dig > 0 then begin
  176. t:= dig mod 100;
  177. h:= dig div 100;
  178. if h > 0 then begin
  179. TensToText(s, h);
  180. if t > 0 then begin
  181. s:= s + ' houndred ';
  182. TensToText(s1, t);
  183. s:= s + s1;
  184. end else
  185. s:= s + ' houndred';
  186. end else
  187. TensToText(s, t);
  188. end else
  189. s:= '';
  190. end;
  191. var
  192. dig, h: Integer;
  193. s1: string;
  194. begin
  195. if n > 0 then begin
  196. dig:= n div 1000;
  197. h:= n mod 1000;
  198. if dig > 0 then begin
  199. HundredsToText(s, dig);
  200. if h > 0 then begin
  201. s:= s + ' thousand ';
  202. HundredsToText(s1, h);
  203. s:= s + s1;
  204. end else
  205. s:= s + ' thousand';
  206. end else
  207. HundredsToText(s, h);
  208. end else
  209. s:= Number1[0];
  210. end;
  211. function NumberToText_V3(n: Integer): string;
  212. function TensToText(dig: Integer): string;
  213. var
  214. x: Integer;
  215. begin
  216. if dig > 0 then begin
  217. if dig >= 20 then begin
  218. x:= dig mod 10;
  219. if x <> 0 then begin
  220. Result:= Number10[dig div 10] + Number9[x]
  221. end else
  222. Result:= Number10[dig div 10];
  223. end else begin
  224. Result:= Number1[dig];
  225. end;
  226. end else
  227. Result:= '';
  228. end;
  229. function HundredsToText(dig: Integer): string;
  230. var
  231. h, t: Integer;
  232. begin
  233. if dig > 0 then begin
  234. t:= dig mod 100;
  235. h:= dig div 100;
  236. if h > 0 then begin
  237. if t > 0 then
  238. Result:= TensToText(h) + ' houndred ' + TensToText(t)
  239. else
  240. Result:= TensToText(h) + ' houndred';
  241. end else
  242. Result:= TensToText(t);
  243. end else
  244. Result:= '';
  245. end;
  246. var
  247. dig, h: Integer;
  248. begin
  249. if n > 0 then begin
  250. dig:= n div 1000;
  251. h:= n mod 1000;
  252. if dig > 0 then begin
  253. if h > 0 then
  254. Result:= HundredsToText(dig) + ' thousand ' + HundredsToText(h)
  255. else
  256. Result:= HundredsToText(dig) + ' thousand';
  257. end else
  258. Result:= HundredsToText(h);
  259. end else
  260. Result:= Number1[0];
  261. end;
  262. procedure Test1;
  263. var
  264. StartTick: Cardinal;
  265. i: Integer;
  266. s: string;
  267. begin
  268. StartLog(StartTick);
  269. for i:= 1 to cTimes do begin
  270. NumberToText_V1(s, i);
  271. end;
  272. EndLog('Test 1', StartTick, cTimes);
  273. end;
  274. procedure Test2;
  275. var
  276. StartTick: Cardinal;
  277. i: Integer;
  278. s: string;
  279. begin
  280. StartLog(StartTick);
  281. for i:= 1 to cTimes do begin
  282. NumberToText_V2(s, i);
  283. end;
  284. EndLog('Test 2', StartTick, cTimes);
  285. end;
  286. procedure Test3;
  287. var
  288. StartTick: Cardinal;
  289. i: Integer;
  290. s: string;
  291. begin
  292. StartLog(StartTick);
  293. for i:= 1 to cTimes do begin
  294. s:= NumberToText_V3(i);
  295. end;
  296. EndLog('Test 3', StartTick, cTimes);
  297. end;
  298. procedure Benchmark;
  299. var
  300. I: integer;
  301. begin
  302. for I := 1 to BenchCount do
  303. begin
  304. Test1;
  305. Test2;
  306. Test3;
  307. end;
  308. end;