Search code examples
c++mathfractions

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.


Solution

  • 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.