Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How many digits in this base?

The problem is to derive a formula for determining number of digits a given decimal number could have in a given base.

For example: The decimal number 100006 can be represented by 17,11,9,8,7,6,8 digits in bases 2,3,4,5,6,7,8 respectively.

Well the formula I derived so far is like this : (log10(num) /log10(base)) + 1.

in C/C++ I used this formula to compute the above given results.

long long int size = ((double)log10(num) / (double)log10(base)) + 1.0;

But sadly the formula is not giving correct answer is some cases,like these :

Number 8 in  base 2 : 1,0,0,0
Number of digits: 4
Formula returned: 3

Number 64 in  base 2 : 1,0,0,0,0,0,0
Number of digits: 7
Formula returned: 6

Number 64 in  base 4 : 1,0,0,0
Number of digits: 4
Formula returned: 3

Number 125 in  base 5 : 1,0,0,0
Number of digits: 4
Formula returned: 3

Number 128 in  base 2 : 1,0,0,0,0,0,0,0
Number of digits: 8
Formula returned: 7

Number 216 in  base 6 : 1,0,0,0
Number of digits: 4
Formula returned: 3

Number 243 in  base 3 : 1,0,0,0,0,0
Number of digits: 6
Formula returned: 5

Number 343 in  base 7 : 1,0,0,0
Number of digits: 4
Formula returned: 3

So the error is by 1 digit.I just want somebody to help me to correct the formula so that it work for every possible cases.

Edit : As per the input specification I have to deal with cases like 10000000000, i.e 10^10,I don't think log10() in either C/C++ can handle such cases ? So any other procedure/formula for this problem will be highly appreciated.

like image 516
whacko__Cracko Avatar asked Dec 04 '09 14:12

whacko__Cracko


1 Answers

There are fast floating operations in your compiler settings. You need precise floation operations. The thing is that log10(8)/log10(2) is always 3 in math. But may be your result is 2.99999, for expample. It is bad. You must add small additive, but not 0.5. It should be about .00001 or something like that.

Almost true formula:

int size = static_cast<int>((log10((double)num) / log10((double)base)) + 1.00000001);

Really true solution

You should check the result of your formula. Compexity is O(log log n) or O(log result)!

int fast_power(int base, int s)
{
    int res = 1;
    while (s) {
        if (s%2) {
            res*=base;
            s--;
        } else {
            s/=2;
            base*=base;
        }
    }
    return res;
}

int digits_size(int n, int base)
{
    int s = int(log10(1.0*n)/log10(1.0*base)) + 1;
    return fast_power(base, s) > n ? s : s+1;
}

This check is better than Brute-force test with base multiplications.

like image 93
Alexey Malistov Avatar answered Sep 21 '22 14:09

Alexey Malistov