# Counting the Digits

I am not a math genius, as any math genius who reviews my work is happy to tell me. Even so, when programming I’m often faced with math challenges where a math education would benefit. My most recent puzzle is how to count the number of digits in a value without first converting the value into a string.

If you visit this blog regularly, yes, this Lesson hints at an upcoming Exercise challenge. Still, the problem intrigued me: Does some mathematical trick exist that determines how a value such as 12345 contains five digits? Rather than research such a solution, I just started to code. Typical.

Given the Power of the Computer, I devised a brute-force method to determine the number of digits in a value by subtracting successive powers of 10 from a given number. To ensure that large values are properly processed, I use long integer types in the following code:

### 2022_08_20-Lesson-a.c

```#include <stdio.h>

int main()
{
long d;
int x,l;
long value[10] = {
1, 12, 123, 1234, 12345,
123456, 1234567, 12345678,
123456789, 1234567890
};

for( x=0; x<10; x++ )
{
l=d=1;
while( d<=10000000000 )
{
if( value[x]<d )
{
printf("%ld is %d digits long\n",value[x],l-1);
break;
}
d*=10;
l++;
}
}

return(0);
}```

The `value[]` array holds ten numbers progressing from 1 through 1234567890. A for loop churns through each of the values.

Within the for loop, a while loop compares `value[x]` with successive powers of 10. The looping value `d` starts at one, and multiplies itself by 10 each iteration until its value equals 10,000,000,000.

Within the while loop, an if statement compares the value submitted, `value[x]`, with `d`, the power of 10. When the value is less, then digit counter variable `l` (little L) determines the number of digits. Here is the output:

```1 is 1 digits long 12 is 2 digits long 123 is 3 digits long 1234 is 4 digits long 12345 is 5 digits long 123456 is 6 digits long 1234567 is 7 digits long 12345678 is 8 digits long 123456789 is 9 digits long 1234567890 is 10 digits long```

This test works fine, but what I truly adore is generating random numbers to try the code. The problem here is that random values are typically and uniformly huge, so they must be pared down to a smaller length. Such an exercise requires more math magic, at which I confess to being a poor conjurer. Still, I took a stab at it in this update to the code:

### 2022_08_20-Lesson-b.c

```#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int main()
{
long d;
int l,r;
long value;

/* seed the randomizer */
srand( (unsigned)time(NULL) );

/* obtain the random value */
value = rand();

/* obtain a random value length */
r = rand() % 11;

/* truncate the value */
value %= (int)pow(10,r);

/*
now count the digits, which will end
up being the same value as 'r', but
what-the-hey
*/
l=d=1;
while( d<=10000000000 )
{
if( value<d )
{
printf("%ld is %d digits long\n",value,l-1);
break;
}
d*=10;
l++;
}

return(0);
}```

Two random values are required to generate a random number of a random length. The first is the value itself, `value` in the above code. The second is the truncating value, `r` above.

At Line 22, `value` is truncated by taking `r` to the power of 10, typecasting it as an integer, and using the mod assignment operator, `%=`. This expression reduces the random `value` down to a digit range equal to the value of `r` — which is what the remainder of the code attempts to discover. Still, the point is to try the technique on a random value, and it works:

```36398 is 5 digits long 9070012 is 7 digits long 99086819 is 8 digits long 599137240 is 9 digits long 4 is 1 digits long```

I would bet a whole donut that a better way exists to count the digits in a number. If not a better way, perhaps even a different way that makes more sense. If you know of one, please let me know. I’m not desperate, just curious.

## 5 thoughts on “Counting the Digits”

1. I think you should be able to do something with logarithms (base 10).

Why did you think it necessary to specify “whole” donut? I don’t think anyone would assume you meant a half eaten one ðŸ™‚

2. Yep, there’s that maths thing: I would never assume logarithms because it was two week of school and then we moved on. I looked for a book on logarithms a while back. Nada. The only one I found was tepid.

Donuts are precious.

3. This is a selection of numbers with their base 10 logarithms:

1 – 0
2 – 0.301030
9 – 0.954243

10 – 1
99 – 1.995635

100 – 2
999 – 2.999565

1000 – 3
9999 – 3.999957

10000 – 4
99999 – 4.999996

100000 – 5
999999 – 5.999999

so all you need to do is round the logarithm down to the nearest integer and add 1, eg

digits = floor(log10(n)) + 1;

4. I’m not professional programmer, but this type of problems, counting digits in a number, i’ve always done it this way:

long number;
int digits = 0;
while (number)
{
digits++;
number /= 10;
}