Forum > Beginners

simple problem: count digits of number

<< < (2/9) > >>

Bart:

--- Quote from: furious programming on February 05, 2018, 05:43:04 am ---
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Count := MyIntVar.ToString.Length;
--- End quote ---

That's basically the same as I wrote above (Length(IntToStr(InZahl))), proabbly a bit less efficient (unless all this code for the helper is inlined), albeit more fancy.
The Log10 approach might actually be faster?

Bart

isidroco:
Floating point Log will always be slower, it involves series calculation even when done in mathcoprocessor will be slow, and sending/getting results from coprocessor will probably be slower than integer operations unless number of digits is very big (>50) in which log10 might be faster.

PS: In my old days when clocking stuff in 80286 cpus, I found out in TP5.0 that x*0.33333333 was a lot faster than x/3. (x: real) (And a lot was about 3 times faster). So it's better to multiply by a constant than divide by it's inverse.

A.S.:
Function "countZiff" is incorrect: it returns 0 if inZahl=0, but "0" contains the single digit zero, so countZiff(0) must return 1.

Bart:

--- Quote from: isidroco on February 28, 2018, 07:43:43 pm ---Floating point Log will always be slower, it involves series calculation even when done in mathcoprocessor will be slow, and sending/getting results from coprocessor will probably be slower than integer operations unless number of digits is very big (>50) in which log10 might be faster.

--- End quote ---

The IntToStr part also costs time.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program Project1;{\$mode objfpc}{\$h+} uses SysUtils, Math; function cntIntToStr(Z: Integer): Integer;begin  Result := Length(IntToStr(Z));end; function cntTypeHelper(Z: Integer): Integer;begin  Result := Z.ToString.Length;end; function cntLog10(Z: Integer): Integer;begin  if Z = 0 then    Result := 1  else    Result := 1+Floor(Log10(Z));end; const  cycle = 1000000;var  i: Integer;  T0, T1: QWord;  Sample, Res: Integer;begin  Sample := MaxInt; //2147483647   T0 := GetTickCount64;  for i := 1 to cycle do Res := cntIntToStr(Sample);  T1 := GetTickCount64;  writeln(format('cntIntToStr  : %.4d ticks (Res = %d)',[T1-T0,Res]));   T0 := GetTickCount64;  for i := 1 to cycle do Res := cntTypeHelper(Sample);  T1 := GetTickCount64;  writeln(format('cntTypeHelper: %.4d ticks (Res = %d)',[T1-T0,Res]));   T0 := GetTickCount64;  for i := 1 to cycle do Res := cntLog10(Sample);  T1 := GetTickCount64;  writeln(format('cntLog10     : %.4d ticks (Res = %d)',[T1-T0,Res]));end.
Outputs:

--- Code: ---cntIntToStr  : 1328 ticks (Res = 10)
cntTypeHelper: 1359 ticks (Res = 10)
cntLog10     : 0047 ticks (Res = 10)

--- End code ---

Notice that using typehelpers this is just a little bit slower than using classic Length(IntToStr()), but the Log10 is way faster.

Bart

isidroco:

--- Quote from: Bart on February 28, 2018, 10:30:37 pm ---Notice that using typehelpers this is just a little bit slower than using classic Length(IntToStr()), but the Log10 is way faster.
Bart

--- End quote ---

Thanks for the eyeopener, evidently TP5 real type without using coprocessor were a lot slower than today's implementation which uses it. And IntToStr involves a lot of DIV instructions. (In my days 80387 math coprocessor costed 800u\$ so most machines didn't have it...). Actually I had to program log(X+1) and it's inverse using taylor series, and it was quite faster than using internal LOG(x+1) for values of x close to 0. Math coprocessor have internal instructions for that: FYL2XP1 / F2XM1