Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retrieve the first decimal digit of number efficiently

Tags:

c++

c

algorithm

One obvious solution is:

int n = 2134;
while(n > 9)
    n /= 10;

which takes linear time. Could we do any faster?

Is this any faster than linear time:

char s[100];
sprintf(s, "%d", n);
n = s[0]-'0';

Which are the other ways (efficiency is primary concern)?
I've seen this, except that I need to find only the first digit. (Also, I don't understand the answer).

like image 368
mohit Avatar asked Jun 30 '13 18:06

mohit


People also ask

How do I extract the first digit of a number?

To find last digit of a number, we use modulo operator %. When modulo divided by 10 returns its last digit. To finding first digit of a number is little expensive than last digit. To find first digit of a number we divide the given number by 10 until number is greater than 10.

Where is the first digit in a number?

The first digit 1 is in the Hundreds place and has a value of One hundred. The second digit 1 is in the Tens place and has a value of Ten. The digit 2 is in the Ones place and has a value of Two.

How do you get the first digit of a number in Python?

To get the first digit, we can use the Python math log10() function. In the loop example, we divided by 10 until we got to a number between 0 and 10. By using the log10() function, we can find out exactly how many times we need to divide by 10 and then do the division directly.


2 Answers

Some processors have instructions that calculate "how big" a number is, very quickly (see http://en.wikipedia.org/wiki/Leading_zero_count). This can be used to quickly choose a power of 10, and divide by it, instead of dividing by 10 repeatedly.

Suppose you are given a function clz that calculates the number of leading zero bits in a number's binary representation (0...32). Then, you can use a lookup table that gives the proper power of 10 for each number of leading zeros.

uint32_t powers_of_10[33] = {
    1000000000, 1000000000,
    100000000, 100000000, 100000000,
    10000000, 10000000, 10000000,
    1000000, 1000000, 1000000, 1000000,
    100000, 100000, 100000,
    10000, 10000, 10000,
    1000, 1000, 1000, 1000,
    100, 100, 100,
    10, 10, 10,
    1, 1, 1, 1, 1
};

int CalcFirstDecimalDigit(uint32_t x)
{
    int leading_zeros = clz(x);
    x /= powers_of_10[leading_zeros];
    if (x >= 10)
        return 1;
    else
        return x;
}
like image 173
anatolyg Avatar answered Oct 05 '22 12:10

anatolyg


e.g. for in 32 bit unsigned:

Step 1: determine (by binary search) in which of the following intervals the value is:

0 .. 9
10 .. 99
100 .. 999
1000 .. 9999
10000 .. 99999
100000 .. 999999
1000000 .. 9999999
10000000 .. 99999999
100000000 .. 999999999
1000000000 .. 4294967295

takes max 4 compares

Step 2:

Than calculate the leading digit by one division.

like image 31
MrSmith42 Avatar answered Oct 05 '22 13:10

MrSmith42