Recent

Author Topic: Alternative set of string-to-int conversion routines  (Read 26344 times)

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Alternative set of string-to-int conversion routines
« Reply #30 on: January 21, 2022, 01:08:26 pm »
Of course, I have some understanding of the current possibilities of generics, but so far this does not in any way stimulate the choice in their favor due to the above reason.
On the other hand, is duplication of code in a library so bad? Indeed, in this case, changes in the code of some function will not affect others.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5444
  • Compiler Developer
Re: Alternative set of string-to-int conversion routines
« Reply #31 on: January 21, 2022, 03:51:40 pm »
Generic functions need to be declared in the interface part of the unit, and since they are helpers, this is not very good.

Why do you say that generic functions need to be declared in the interface part of the unit?

I know your point of view - it's not a compiler problem, it's a bad programmer's problem)) But no. Debugging the code is also necessary inside the genetic classes and it is very difficult
Well, no, that is not what I wrote. Both ways to specialize are fully legal.
Specialized at type level it isn't even possible - by sheer logic - to debug the template code, afaik there is none.
Maybe @PascalDragon can help us here.... Sarah? Or @FPK himself?

If there are concrete issues with debugging then we need a reproducible example no matter the issue, cause, yes, such things should be fixed, no matter if it's about stepping through generic code correctly or not accidentally entering generic code when one doesn't want it as MarkMLI hinted at.

One potential issue might be (not tested): the generic code is compiled without debug information, but code that uses it is compiled with and thus the specialization will have debug information as well. Thus when stepping through the latter code one might suddenly land in the generic code which one assumed is without debug information.

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Alternative set of string-to-int conversion routines
« Reply #32 on: January 21, 2022, 04:13:01 pm »
Why do you say that generic functions need to be declared in the interface part of the unit?
Probably lagged behind life, some time ago it was like that, but now I didn’t even try to check. :-[
Thank you.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6647
Re: Alternative set of string-to-int conversion routines
« Reply #33 on: January 21, 2022, 04:49:00 pm »
One potential issue might be (not tested): the generic code is compiled without debug information, but code that uses it is compiled with and thus the specialization will have debug information as well. Thus when stepping through the latter code one might suddenly land in the generic code which one assumed is without debug information.

On the other hand, I invariably use a locally-built FPC+Lazarus and looking at my build log for FPC 3.2.0 I see

make NO_GDB=1 CPU_TARGET=i386 OPT='-V3.0.4 -O- -gl -Xs- -vt' all |/usr/local/bin/fpc-filter-vt

Lazarus+LCL though is built with default options, so it could be there.

I'll try to keep an eye open for what I think I've seen, and will report back.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Alternative set of string-to-int conversion routines
« Reply #34 on: January 22, 2022, 11:40:01 am »
Some news from str2int-alter:
  current version has switched to generics;
  added define to force full compatibility with Val();
  added benchmarks for unsigned integers, now it looks like this on my virtual Linux machine:
Code: Text  [Select][+][-]
  1. SInt32:
  2. Val(), score:        3071
  3. TryChars2Int, score: 1250
  4.  
  5. SInt64:
  6. Val(), score:        3131
  7. TryChars2Int, score: 1177
  8.  
  9. UInt32:
  10. Val(), score:        5619
  11. TryChars2Int, score: 1248
  12.  
  13. UInt64:
  14. Val(), score:        7015
  15. TryChars2Int, score: 1280
  16.  

Thaddy

  • Hero Member
  • *****
  • Posts: 14168
  • Probably until I exterminate Putin.
Re: Alternative set of string-to-int conversion routines
« Reply #35 on: January 22, 2022, 12:01:58 pm »
Nice gain.
Specialize a type, not a var.

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Alternative set of string-to-int conversion routines
« Reply #36 on: January 24, 2022, 09:37:56 am »
Sorry, couldn't resist, found the old benchmark archive from "Sorting and Counting" and ran it again using Str2IntAlter on a win-64 machine:
Code: Text  [Select][+][-]
  1. RandomRange = 1
  2. Julkas1's time: 3.3850  #unique: 100000 #total: 10000000
  3. Julkas2's time: 3.4820  #unique: 100000 #total: 10000000
  4.   Akira's time: 3.1700  #unique: 100000 #total: 10000000
  5.  Howard's time: 4.6500  #unique: 100000 #total: 10000000
  6.    Avk1's time: 1.3300  #unique: 100000 #total: 10000000
  7.    Avk2's time: 0.6100  #unique: 100000 #total: 10000000
  8.   440bx's time: 1.5100  #unique: 100000 #total: 10000000
  9.  BrunoK's time: 1.6900  #unique: 100000 #total: 10000000
  10. BrunoK1's time: 1.1200  #unique: 100000 #total: 10000000
  11.  
  12. RandomRange = 2
  13. Julkas1's time: 3.4000  #unique: 200000 #total: 10000000
  14. Julkas2's time: 3.4500  #unique: 200000 #total: 10000000
  15.   Akira's time: 3.3400  #unique: 200000 #total: 10000000
  16.  Howard's time: 4.6900  #unique: 200000 #total: 10000000
  17.    Avk1's time: 1.3600  #unique: 200000 #total: 10000000
  18.    Avk2's time: 0.6400  #unique: 200000 #total: 10000000
  19.   440bx's time: 1.6200  #unique: 200000 #total: 10000000
  20.  BrunoK's time: 1.7800  #unique: 200000 #total: 10000000
  21. BrunoK1's time: 1.1700  #unique: 200000 #total: 10000000
  22.  
  23. RandomRange = 3
  24. Julkas1's time: 3.4300  #unique: 300000 #total: 10000000
  25. Julkas2's time: 3.4300  #unique: 300000 #total: 10000000
  26.   Akira's time: 3.4300  #unique: 300000 #total: 10000000
  27.  Howard's time: 4.7500  #unique: 300000 #total: 10000000
  28.    Avk1's time: 1.3900  #unique: 300000 #total: 10000000
  29.    Avk2's time: 0.6700  #unique: 300000 #total: 10000000
  30.   440bx's time: 1.6800  #unique: 300000 #total: 10000000
  31.  BrunoK's time: 1.8300  #unique: 300000 #total: 10000000
  32. BrunoK1's time: 1.2500  #unique: 300000 #total: 10000000
  33.  
  34. RandomRange = 4
  35. Julkas1's time: 3.5400  #unique: 400000 #total: 10000000
  36. Julkas2's time: 3.4700  #unique: 400000 #total: 10000000
  37.   Akira's time: 3.6200  #unique: 400000 #total: 10000000
  38.  Howard's time: 4.8200  #unique: 400000 #total: 10000000
  39.    Avk1's time: 1.4200  #unique: 400000 #total: 10000000
  40.    Avk2's time: 0.7100  #unique: 400000 #total: 10000000
  41.   440bx's time: 1.7400  #unique: 400000 #total: 10000000
  42.  BrunoK's time: 1.8900  #unique: 400000 #total: 10000000
  43. BrunoK1's time: 1.3100  #unique: 400000 #total: 10000000
  44.  
  45. RandomRange = 5
  46. Julkas1's time: 3.5000  #unique: 500000 #total: 10000000
  47. Julkas2's time: 3.5000  #unique: 500000 #total: 10000000
  48.   Akira's time: 3.7200  #unique: 500000 #total: 10000000
  49.  Howard's time: 4.9000  #unique: 500000 #total: 10000000
  50.    Avk1's time: 1.4600  #unique: 500000 #total: 10000000
  51.    Avk2's time: 0.7400  #unique: 500000 #total: 10000000
  52.   440bx's time: 1.7900  #unique: 500000 #total: 10000000
  53.  BrunoK's time: 1.9300  #unique: 500000 #total: 10000000
  54. BrunoK1's time: 1.3400  #unique: 500000 #total: 10000000
  55.  
  56. RandomRange = 6
  57. Julkas1's time: 3.5400  #unique: 600000 #total: 10000000
  58. Julkas2's time: 3.5200  #unique: 600000 #total: 10000000
  59.   Akira's time: 3.7700  #unique: 600000 #total: 10000000
  60.  Howard's time: 5.0000  #unique: 600000 #total: 10000000
  61.    Avk1's time: 1.4800  #unique: 600000 #total: 10000000
  62.    Avk2's time: 0.7800  #unique: 600000 #total: 10000000
  63.   440bx's time: 1.8400  #unique: 600000 #total: 10000000
  64.  BrunoK's time: 1.9900  #unique: 600000 #total: 10000000
  65. BrunoK1's time: 1.3900  #unique: 600000 #total: 10000000
  66.  
  67. RandomRange = 7
  68. Julkas1's time: 3.5700  #unique: 700000 #total: 10000000
  69. Julkas2's time: 3.5800  #unique: 700000 #total: 10000000
  70.   Akira's time: 3.8300  #unique: 700000 #total: 10000000
  71.  Howard's time: 5.0600  #unique: 700000 #total: 10000000
  72.    Avk1's time: 1.5300  #unique: 700000 #total: 10000000
  73.    Avk2's time: 0.8000  #unique: 700000 #total: 10000000
  74.   440bx's time: 1.9000  #unique: 700000 #total: 10000000
  75.  BrunoK's time: 2.0100  #unique: 700000 #total: 10000000
  76. BrunoK1's time: 1.4200  #unique: 700000 #total: 10000000
  77.  
  78. RandomRange = 8
  79. Julkas1's time: 3.5900  #unique: 799994 #total: 10000000
  80. Julkas2's time: 3.6100  #unique: 799994 #total: 10000000
  81.   Akira's time: 3.9000  #unique: 799994 #total: 10000000
  82.  Howard's time: 5.1400  #unique: 799994 #total: 10000000
  83.    Avk1's time: 1.5800  #unique: 799994 #total: 10000000
  84.    Avk2's time: 0.8400  #unique: 799994 #total: 10000000
  85.   440bx's time: 1.9400  #unique: 799994 #total: 10000000
  86.  BrunoK's time: 2.0800  #unique: 799994 #total: 10000000
  87. BrunoK1's time: 1.4700  #unique: 799994 #total: 10000000
  88.  
  89. RandomRange = 9
  90. Julkas1's time: 3.6300  #unique: 899990 #total: 10000000
  91. Julkas2's time: 3.6300  #unique: 899990 #total: 10000000
  92.   Akira's time: 3.9400  #unique: 899990 #total: 10000000
  93.  Howard's time: 5.2100  #unique: 899990 #total: 10000000
  94.    Avk1's time: 1.5800  #unique: 899990 #total: 10000000
  95.    Avk2's time: 0.8600  #unique: 899990 #total: 10000000
  96.   440bx's time: 1.9800  #unique: 899990 #total: 10000000
  97.  BrunoK's time: 2.0900  #unique: 899990 #total: 10000000
  98. BrunoK1's time: 1.5200  #unique: 899990 #total: 10000000
  99.  
  100. RandomRange = 10
  101. Julkas1's time: 3.6600  #unique: 999962 #total: 10000000
  102. Julkas2's time: 3.6400  #unique: 999962 #total: 10000000
  103.   Akira's time: 4.0100  #unique: 999962 #total: 10000000
  104.  Howard's time: 5.2700  #unique: 999962 #total: 10000000
  105.    Avk1's time: 1.6100  #unique: 999962 #total: 10000000
  106.    Avk2's time: 0.9000  #unique: 999962 #total: 10000000
  107.   440bx's time: 2.0200  #unique: 999962 #total: 10000000
  108.  BrunoK's time: 2.1300  #unique: 999962 #total: 10000000
  109. BrunoK1's time: 1.5500  #unique: 999962 #total: 10000000
  110.  
  111. repeatMillionsCount = 2
  112. Julkas1's time: 0.8800  #unique: 734359 #total: 2000000
  113. Julkas2's time: 0.8600  #unique: 734359 #total: 2000000
  114.   Akira's time: 1.0700  #unique: 734359 #total: 2000000
  115.  Howard's time: 1.2010  #unique: 734359 #total: 2000000
  116.    Avk1's time: 0.4200  #unique: 734359 #total: 2000000
  117.    Avk2's time: 0.2700  #unique: 734359 #total: 2000000
  118.   440bx's time: 0.5000  #unique: 734359 #total: 2000000
  119.  BrunoK's time: 0.5800  #unique: 734359 #total: 2000000
  120. BrunoK1's time: 0.4700  #unique: 734359 #total: 2000000
  121.  
  122. repeatMillionsCount = 4
  123. Julkas1's time: 1.7400  #unique: 794586 #total: 4000000
  124. Julkas2's time: 1.5600  #unique: 794586 #total: 4000000
  125.   Akira's time: 1.8300  #unique: 794586 #total: 4000000
  126.  Howard's time: 2.1900  #unique: 794586 #total: 4000000
  127.    Avk1's time: 0.7000  #unique: 794586 #total: 4000000
  128.    Avk2's time: 0.4100  #unique: 794586 #total: 4000000
  129.   440bx's time: 0.8900  #unique: 794586 #total: 4000000
  130.  BrunoK's time: 0.9500  #unique: 794586 #total: 4000000
  131. BrunoK1's time: 0.7400  #unique: 794586 #total: 4000000
  132.  
  133. repeatMillionsCount = 6
  134. Julkas1's time: 2.2500  #unique: 799541 #total: 6000000
  135. Julkas2's time: 2.2400  #unique: 799541 #total: 6000000
  136.   Akira's time: 2.5200  #unique: 799541 #total: 6000000
  137.  Howard's time: 3.1700  #unique: 799541 #total: 6000000
  138.    Avk1's time: 0.9900  #unique: 799541 #total: 6000000
  139.    Avk2's time: 0.5700  #unique: 799541 #total: 6000000
  140.   440bx's time: 1.2500  #unique: 799541 #total: 6000000
  141.  BrunoK's time: 1.3400  #unique: 799541 #total: 6000000
  142. BrunoK1's time: 0.9800  #unique: 799541 #total: 6000000
  143.  
  144. repeatMillionsCount = 8
  145. Julkas1's time: 2.9200  #unique: 799966 #total: 8000000
  146. Julkas2's time: 2.9200  #unique: 799966 #total: 8000000
  147.   Akira's time: 3.2100  #unique: 799966 #total: 8000000
  148.  Howard's time: 4.5520  #unique: 799966 #total: 8000000
  149.    Avk1's time: 1.8860  #unique: 799966 #total: 8000000
  150.    Avk2's time: 0.9000  #unique: 799966 #total: 8000000
  151.   440bx's time: 1.8020  #unique: 799966 #total: 8000000
  152.  BrunoK's time: 1.8100  #unique: 799966 #total: 8000000
  153. BrunoK1's time: 1.3400  #unique: 799966 #total: 8000000
  154.  
  155. repeatMillionsCount = 10
  156. Julkas1's time: 3.7200  #unique: 799998 #total: 10000000
  157. Julkas2's time: 3.6100  #unique: 799998 #total: 10000000
  158.   Akira's time: 3.9300  #unique: 799998 #total: 10000000
  159.  Howard's time: 5.1600  #unique: 799998 #total: 10000000
  160.    Avk1's time: 1.5500  #unique: 799998 #total: 10000000
  161.    Avk2's time: 0.8500  #unique: 799998 #total: 10000000
  162.   440bx's time: 1.9400  #unique: 799998 #total: 10000000
  163.  BrunoK's time: 2.0800  #unique: 799998 #total: 10000000
  164. BrunoK1's time: 1.4800  #unique: 799998 #total: 10000000
  165.  
  166. repeatMillionsCount = 12
  167. Julkas1's time: 4.3900  #unique: 799999 #total: 12000000
  168. Julkas2's time: 4.2600  #unique: 799999 #total: 12000000
  169.   Akira's time: 4.6000  #unique: 799999 #total: 12000000
  170.  Howard's time: 6.1300  #unique: 799999 #total: 12000000
  171.    Avk1's time: 1.9300  #unique: 799999 #total: 12000000
  172.    Avk2's time: 0.9700  #unique: 799999 #total: 12000000
  173.   440bx's time: 2.2900  #unique: 799999 #total: 12000000
  174.  BrunoK's time: 2.4300  #unique: 799999 #total: 12000000
  175. BrunoK1's time: 1.7100  #unique: 799999 #total: 12000000
  176.  
  177. repeatMillionsCount = 14
  178. Julkas1's time: 4.9900  #unique: 799999 #total: 14000000
  179. Julkas2's time: 4.9600  #unique: 799999 #total: 14000000
  180.   Akira's time: 5.3200  #unique: 799999 #total: 14000000
  181.  Howard's time: 7.1200  #unique: 799999 #total: 14000000
  182.    Avk1's time: 2.0900  #unique: 799999 #total: 14000000
  183.    Avk2's time: 1.0800  #unique: 799999 #total: 14000000
  184.   440bx's time: 2.6300  #unique: 799999 #total: 14000000
  185.  BrunoK's time: 2.8000  #unique: 799999 #total: 14000000
  186. BrunoK1's time: 1.9800  #unique: 799999 #total: 14000000
  187.  
  188. repeatMillionsCount = 16
  189. Julkas1's time: 5.6700  #unique: 800000 #total: 16000000
  190. Julkas2's time: 5.6200  #unique: 800000 #total: 16000000
  191.   Akira's time: 5.9900  #unique: 800000 #total: 16000000
  192.  Howard's time: 8.1000  #unique: 800000 #total: 16000000
  193.    Avk1's time: 2.3600  #unique: 800000 #total: 16000000
  194.    Avk2's time: 1.2200  #unique: 800000 #total: 16000000
  195.   440bx's time: 2.9800  #unique: 800000 #total: 16000000
  196.  BrunoK's time: 3.1800  #unique: 800000 #total: 16000000
  197. BrunoK1's time: 2.2000  #unique: 800000 #total: 16000000
  198.  
  199. repeatMillionsCount = 18
  200. Julkas1's time: 6.3200  #unique: 800000 #total: 18000000
  201. Julkas2's time: 6.2900  #unique: 800000 #total: 18000000
  202.   Akira's time: 6.6800  #unique: 800000 #total: 18000000
  203.  Howard's time: 9.0600  #unique: 800000 #total: 18000000
  204.    Avk1's time: 2.6700  #unique: 800000 #total: 18000000
  205.    Avk2's time: 1.3900  #unique: 800000 #total: 18000000
  206.   440bx's time: 3.3400  #unique: 800000 #total: 18000000
  207.  BrunoK's time: 3.5700  #unique: 800000 #total: 18000000
  208. BrunoK1's time: 2.4400  #unique: 800000 #total: 18000000
  209.  
  210. repeatMillionsCount = 20
  211. Julkas1's time: 7.0000  #unique: 800000 #total: 20000000
  212. Julkas2's time: 6.9700  #unique: 800000 #total: 20000000
  213.   Akira's time: 7.4000  #unique: 800000 #total: 20000000
  214.  Howard's time: 10.0600 #unique: 800000 #total: 20000000
  215.    Avk1's time: 2.9500  #unique: 800000 #total: 20000000
  216.    Avk2's time: 1.5100  #unique: 800000 #total: 20000000
  217.   440bx's time: 3.6700  #unique: 800000 #total: 20000000
  218.  BrunoK's time: 3.9000  #unique: 800000 #total: 20000000
  219. BrunoK1's time: 2.6900  #unique: 800000 #total: 20000000
  220.  
Procedure Avk1 reads the input data from stdin, Avk2 loads the entire input file into TMemoryStream.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5444
  • Compiler Developer
Re: Alternative set of string-to-int conversion routines
« Reply #37 on: January 24, 2022, 01:31:49 pm »
Why do you say that generic functions need to be declared in the interface part of the unit?
Probably lagged behind life, some time ago it was like that, but now I didn’t even try to check. :-[

This works since the introduction of generic functions. Maybe you confused it with the common workaround before generic functions (though even then one does not need to use the interface section):

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. {$modeswitch advancedrecords}
  3.  
  4. type
  5.   generic TGenFuncs<T> = record
  6.     class function Add(aArg1, aArg2: T): T; static;
  7.   end;
  8.  
  9. class function TGenFuncs.Add(aArg1, aArg2: T): T; static;
  10. begin
  11.   Result := aArg1 + aArg2;
  12. end;
  13.  
  14. begin
  15.   Writeln(specialize TGenFuncs<LongInt>(3, 5));
  16. end.

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Alternative set of string-to-int conversion routines
« Reply #38 on: January 24, 2022, 01:57:25 pm »
IIRC at the time when FPC-3.2.0 was not yet released, this method was the only possible one and attempts to declare a generic type in the implementation section were unconditionally suppressed by the compiler.
I just haven't had a need for something like this in a long time.

Zoran

  • Hero Member
  • *****
  • Posts: 1826
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Alternative set of string-to-int conversion routines
« Reply #39 on: January 24, 2022, 03:55:12 pm »
I find it strange that RTL doesn't have a low-level string-to-int function which accepts only decimal (base 10) numbers.

Okay, we don't have it because Delphi doesn't have it. ::)
Which is, again... strange.

Of course it is easy to write a naive implementation, but...
Now we have to check if the two starting characters are decimal digits (not only the first, but the second as well, as val accepts 0x... notation for hex numbers) and only then call val (or TryStrToInt, or your Char2Int), which will again check for binary or hexadecimal notation.

For example:
Code: Pascal  [Select][+][-]
  1. uses
  2.   SysUtils;
  3.  
  4. function StrToIntDecimal(const S: String; out N: Int32): Boolean;
  5. var
  6.   P: PAnsiChar;
  7. begin
  8.   P := PAnsiChar(TrimLeft(S));
  9.   if P^ = '-' then
  10.     Inc(P);
  11.   case P^ of
  12.     '0':
  13.       if not ((P + 1)^ in [#0, '0'..'9']) then
  14.         Exit(False);
  15.     '1'..'9':
  16.       ;
  17.   otherwise
  18.     Exit(False);
  19.   end;
  20.  
  21.   Result := TryStrToInt(S, N);
  22. end;
  23.  

zamtmn

  • Hero Member
  • *****
  • Posts: 593
Re: Alternative set of string-to-int conversion routines
« Reply #40 on: January 24, 2022, 05:04:56 pm »
avk
Perhaps it is worth adding unicode versions? Are there any plans for StrToFloat?

Bart

  • Hero Member
  • *****
  • Posts: 5265
    • Bart en Mariska's Webstek
Re: Alternative set of string-to-int conversion routines
« Reply #41 on: January 24, 2022, 06:44:33 pm »
I find it strange that RTL doesn't have a low-level string-to-int function which accepts only decimal (base 10) numbers.

...

Of course it is easy to write a naive implementation, but...
Now we have to check if the two starting characters are decimal digits (not only the first, but the second as well, as val accepts 0x... notation for hex numbers) and only then call val (or TryStrToInt, or your Char2Int), which will again check for binary or hexadecimal notation.

Val() is the standard function for string to a number, and has been for a very long time.
Specialized and optimized functions (e.g. only base 2) should go into a separate unit IMO.
The checking for base and negativity does not take that much of the time. Most time is doen doing the multiplications and adding and checking that the result won't overflow.
It does the job, and is reliable (at least it is supposed to be and I think it is now).
TryStrToInt and family are supposed to handle the same input as Val() in the same way, so you cannot specialize them for e.g. only base 10.

Personally I think that when you require zillions of string to a number conversions in your program, you should go for a specialized solution.
Such a function can (and probably will) assume certain things about the input (always base 10, not negative, no leading whitespace etc. etc) and may raise exceptions if the input does not match the expectation. That's the trade off.
Such a function most likely will not work on (or be optimized for) all supported fpc platforms (e.g. 8-bit CPU's).
As you can see in this thread many have already implemented such a solution, just pick what you need.

Just my 2 cents.

Bart


avk

  • Hero Member
  • *****
  • Posts: 752
Re: Alternative set of string-to-int conversion routines
« Reply #42 on: January 24, 2022, 06:59:26 pm »
@Zoran:
  It seems that such function, if don't resort to various tricks, will be only slightly faster than the universal one. But it will be possible to try.

@zamtmn:
  To be honest, I have not even thought about unicodestring yet.
Some implementation of the string-to-double conversion function is available in the LGenerics package in the lgJson unit, but it was made purely for the needs of JSON and without much flexibility.
Have you seen this library? 

zamtmn

  • Hero Member
  • *****
  • Posts: 593
Re: Alternative set of string-to-int conversion routines
« Reply #43 on: January 24, 2022, 09:17:31 pm »
avk
>>Have you seen this library?
no, thanks!

BobDog

  • Sr. Member
  • ****
  • Posts: 394
Re: Alternative set of string-to-int conversion routines
« Reply #44 on: January 24, 2022, 11:02:34 pm »
Here is an int64 conversion from ansistring.
float would be the const array extended using 1/10,1/100,1/1000 e.t.c., but i have not tried it yet.
EDITED 25/01/22
Code: Pascal  [Select][+][-]
  1.  
  2. uses
  3. sysutils;
  4.  
  5. function val64( const x:ansistring):int64; inline;
  6.  
  7. const
  8.  p: array[1..20]of qword=(1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000,100000000000, 1000000000000,10000000000000,
  9.                               100000000000000,1000000000000000,10000000000000000,100000000000000000,1000000000000000000,10000000000000000000);
  10.  var
  11.  count:integer=0;
  12.  sp:boolean=false;
  13.  sg:boolean=false;
  14.  n:integer;
  15.  ans:int64=0;
  16.  sign:shortint=1;
  17.  b:byte;
  18.     begin
  19.     for n := length(x) downto  1 do
  20.     begin
  21.     count:=count+1;
  22.     b:=byte(x[n]);
  23.     case b of
  24.    
  25.     32:
  26.     begin
  27.     sp:=true;
  28.     continue;
  29.     end;
  30.    
  31.     45:    
  32.     begin
  33.     sg:=true;
  34.     sign:=-sign;
  35.     if (sign<>-1) then exit(0);
  36.     continue
  37.     end;
  38.    
  39.     48..57:if sp or sg  then exit(0);
  40.     else
  41.     exit(0);
  42.     end;
  43.    
  44.      ans:= ans+p[count] * (b-48);
  45.     end;
  46.     exit( sign*ans);
  47. end;
  48.  
  49. var
  50.  t:int64;
  51.  res:int64;
  52.  code:word;
  53.  k,i:longword;
  54.  
  55.  number:ansistring=' -998880776665550';
  56.  
  57.  
  58. begin
  59.  
  60.  
  61. for k:=1 to 5 do
  62. begin
  63. t:=gettickcount64;
  64. for i:=0 to 10000000 do
  65. res:=val64(number);
  66. writeln(gettickcount64-t,' milliseconds val64 = ',res);
  67.  
  68. t:=gettickcount64;
  69. for i:=0 to 10000000 do
  70. val(number,res,code);
  71. writeln(gettickcount64-t,' milliseconds val =   ',res);
  72. writeln;
  73. end;
  74. writeln('Press enter to end . . .');
  75. readln;
  76. end.
  77.  
  78.  
« Last Edit: January 26, 2022, 12:08:35 am by BobDog »

 

TinyPortal © 2005-2018