Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to count the number of digits in double/float C++

I'm trying to count the number of digits in fractional part of double, but something is going wrong and I getting infinite loop:

double pi = 3.141592;
int counter = 0;
for (; pi != int(pi); ++counter)
    pi *= 10;
cout << counter << endl;

I'v just read about this problem, however I can't find a good solution. Is there really no better way than convert a number to string and count chars? I suppose there's more correct method.

like image 323
hant0508 Avatar asked Dec 10 '22 17:12

hant0508


2 Answers

Floating point numbers in computer use binary (base 2, zeros and ones, like almost all numbers in computers). So there is an exact number of binary digits in them, more in double and less in float. However, if you convert a decimal constant like 3.141592 to double, then print it with full accuracy, you don't get same number back. This is because converting the decimals between bases isn't exact in general (it's similar effect effect you get with 1/3 having infinite decimal expansion 0.33...). Example:

double pi = 3.141592;
std::cout << std::setprecision(100) << pi << std::endl;

Outputs for me:

3.14159200000000016217427400988526642322540283203125

So when you start multiplying this by 10 in your question code, you can see how it doesn't become an exact integer in a long time (and by then it is far beyond range of int), so your condition is never true (either there is fractional part, or the double is too large to fit in integer).

In other words, what you ask, counting digits directly from a double, makes no sense. You first need to print it as string, otherwise you don't really have a number of decimal digits to count. Of course you could micro-optimize this and skip the actual conversion to ASCII or UTF-16 string, but I don't see a scenario where that would be worth the trouble (except perhaps as a learning excercise).

If you need exact decimal digits in calculations, you need a special number type, which doesn't store fractions in binary. Example of such numeric type is Java BigDecimal.

like image 118
hyde Avatar answered Dec 29 '22 15:12

hyde


Atharva MR Fire here.

I've made a simple function that can count number of digits in a double.(float has 8 bits so just change 16 to 8 and make some other necessary changes.)

int get_float_digits(double num)
{
    int digits=0;
    double ori=num;//storing original number
    long num2=num;
    while(num2>0)//count no of digits before floating point
    {
        digits++;
        num2=num2/10;
    }
    if(ori==0)
        digits=1;
    num=ori;
    double no_float;
    no_float=ori*(pow(10, (16-digits)));
    long long int total=(long long int)no_float;
    int no_of_digits, extrazeroes=0;
    for(int i=0; i<16; i++)
    {
        int dig;
        dig=total%10;
        total=total/10;
        if(dig!=0)
            break;
        else
            extrazeroes++;
    }
    no_of_digits=16-extrazeroes;
    return no_of_digits;
}

If you want to get just the number of decimals, add a code no_of_digits=no_of_digits-digits; at the end, before the return function.

I hope this helps.

like image 45
Atharva MR Fire Avatar answered Dec 29 '22 17:12

Atharva MR Fire