program CompareCountDigits;
{$mode objfpc}{$h+}
uses SysUtils, Math;
const
Number: int64 = MaxInt; //2147483647
Iterations: DWord = 1000000;
type
TCountFunc = function(anInt: Int64): Int64;
TFuncEnum = (cfIntToStr, cfTbl, cfTbl64, cfCaseTbl, cfTypeHelper, cfLog10);
TFuncRec = record
func: TCountFunc;
name: String;
end;
TFuncRecArray = array[TFuncEnum] of TFuncRec;
function GetFName(aFuncEnum: TFuncEnum): String;
begin
WriteStr(Result, aFuncEnum);
Delete(Result, 1, 2);
end;
function DoFunction(func: TCountFunc; out ticks: QWord): Int64;
var
i: Integer;
t0: QWord;
begin
t0 := GetTickCount64;
for i := 1 to iterations do
Result := func(Number);
ticks := GetTickCount64;
Dec(ticks, t0);
end;
function cntIntToStr(Z: Int64): Int64;
begin
Result := Length(IntToStr(Z));
end;
function cntTbl(Z: Int64): Int64;
begin
if Z <= 9 then
Result := 1
else if Z <= 99 then
Result := 2
else if Z <= 999 then
Result := 3
else if Z <= 9999 then
Result := 4
else if Z <= 99999 then
Result := 5
else if Z <= 999999 then
Result := 6
else if Z <= 9999999 then
Result := 7
else if Z <= 99999999 then
Result := 8
else if Z <= 999999999 then
Result := 9
else if Z <= 9999999999 then
Result := 10
else if Z <= 99999999999 then
Result := 11
else if Z <= 999999999999 then
Result := 12
else if Z <= 9999999999999 then
Result := 13
else if Z <= 99999999999999 then
Result := 14
else if Z <= 999999999999999 then
Result := 15
else if Z <= 9999999999999999 then
Result := 16
else if Z <= 99999999999999999 then
Result := 17
else if Z <= 999999999999999999 then
Result := 18
else if Z <= 9223372036854775807 then
Result := 19;
end;
function cntCaseTbl(Z: Int64): Int64;
begin
case Z of
0..9: Exit(1);
10..99 : Exit(2);
100..999: Exit(3);
1000..9999: Exit(4);
10000..99999: Exit(5);
100000..999999: Exit(6);
1000000..9999999: Exit(7);
10000000..99999999: Exit(;
100000000..999999999: Exit(9);
1000000000..9999999999: Exit(10);
10000000000..99999999999: Exit(11);
100000000000..999999999999: Exit(12);
1000000000000..9999999999999: Exit(13);
10000000000000..99999999999999: Exit(14);
100000000000000..999999999999999: Exit(15);
1000000000000000..9999999999999999: Exit(16);
10000000000000000..99999999999999999: Exit(17);
100000000000000000..999999999999999999: Exit(18);
1000000000000000000..9223372036854775807: Exit(19);
end;
end;
function cntTbl64(Z: int64): int64;
begin
if Z<0 then Z:=abs(Z);
if Z < 100000000 then
if Z < 10000 then
if Z < 100 then
if Z < 10 then result:=1 else result:=2
else
if Z < 1000 then result:=3 else result:=4
else
if Z < 1000000 then
if Z < 1000000 then result:=5 else result:=6
else
if Z < 10000000 then result:=7 else result:=8
else Exit(8 + cntTbl( z div 100000000) );
end;
function cntTypeHelper(Z: Int64): Int64;
begin
Result := Z.ToString.Length;
end;
function cntLog10(Z: Int64): Int64;
begin
if Z = 0 then
Result := 1
else
Result := 1+Floor(Log10(Z));
end;
var
fra: TFuncRecArray;
fe: TFuncEnum;
fr: TFuncRec;
res: Int64;
ticks: QWord;
begin
fra:=default(TFuncRecArray);
for fe in TFuncEnum do
fra[fe].name := GetFName(fe);
fra[cfIntToStr].func := @cntIntToStr;
fra[cfTbl].func := @cntTbl;
fra[cfTbl64].func := @cntTbl64;
fra[cfCaseTbl].func := @cntCaseTbl;
fra[cfTypeHelper].func:= @cntTypeHelper;
fra[cfLog10].func := @cntLog10;
for fr in fra do begin
res := DoFunction(fr.func, ticks);
WriteLn(fr.name, ticks:4, ' ticks (result = ', res, ')');
end;
ReadLn;
end.