Originally Posted by
ch4
An extra question here
I there another way as simple as log10 is, to calculate the number of digits ?
I can make function to count this number, but i don't think that it is faster than log10.
Depends on the system you are using, whether it can do log10() quickly or not. But it's not JUST the log10 that matters - you get a whole bunch of floating point math operations, that then need to synchronize back to the integer unit.
I did a quick little benchmark of just figuring out the number of digits [yes, it's a quick hack - but I do validate the result]:
Code:
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
int numDigitsLog10(int n)
{
return 1 + log10((float)n);
}
int numDigitsDivide(int n)
{
int d = 0;
do
{
d++;
} while(n /= 10);
return d;
}
int numDigitsRecurse(int n)
{
if (n < 10)
{
return 1;
}
else
{
return 1 + numDigitsRecurse(n / 10);
}
}
#define test(x) { #x, x }
struct testcase
{
char *name;
int (*func)(int);
} testcases[] =
{
test(numDigitsLog10),
test(numDigitsDivide),
test(numDigitsRecurse)
};
const int numIters = 10000000;
int main()
{
struct
{
int n;
int d;
} array[] =
{
{ 100, 3 },
{ 1234, 4 },
{ 631271, 6 },
{ 567801234, 9 }
};
int i, j, k;
for(i = 0; i < sizeof(testcases)/sizeof(testcases[0]); i++)
{
clock_t t = clock();
for(j = 0; j < numIters; j++)
{
for(k = 0; k < sizeof(array)/sizeof(array[0]); k++)
{
int d = testcases[i].func(array[i].n);
if (d != array[i].d)
{
printf("testcase %s failed: for %d expected %d, got %d\n",
testcases[i].name, array[i].n, array[i].d, d);
exit(1);
}
}
}
t = clock() - t;
printf("testcase %s: %6.2f\n",
testcases[i].name, (double) t / CLOCKS_PER_SEC);
}
return 0;
}
Results, using gcc-mingw -O2 -ffast-math:
Code:
testcase numDigitsLog10: 6.53
testcase numDigitsDivide: 0.81
testcase numDigitsRecurse: 1.59
The exact results will of course depend on the processor model. But log10 is not a FAST operation in the floating point unit in any processor.
Actually, whilst writing this reply, I came up with another possible solution, which is faster yet:
Code:
int numDigitsCompare(int n)
{
if (n >= 1000000000)
return 10;
if (n >= 100000000)
return 9;
if (n >= 10000000)
return 8;
if (n >= 1000000)
return 7;
if (n >= 100000)
return 6;
if (n >= 10000)
return 5;
if (n >= 1000)
return 4;
if (n >= 100)
return 3;
if (n >= 10)
return 2;
return 1;
}
Which results in 0.22 seconds runtime (for 10 million times). I have an idea of how to make that one a bit faster too...
--
Mats