The number of digits after the dot in a double number

closed account (436UM4Gy)
Hi all,

consider we have numbers all less than 1 like, 0.2, 0.254, 0.36847, 0.12 and so on and we want to count the number of the digits after the "dot" (.) and this yields 1, 3, 5, 2 for those double numbers in order.
How to do this?

I used this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <std_lib_facilities_4.h>
using namespace std;

int main() 
{
	   int temp = 0;
	   int count = 0;
	   double d = 0.12;

			    if (d < 1)
					do {
						 count++;
						 d *= 10;
					     temp = d;
					     d -= temp;		

				       } while (d != 0);
		cout << count << endl;

  system("pause");
  return 0;
}


But the outcome is not 2, it is 51!
when I checked the code by debug mode, I found that d is stored as 0.12000000000000000 not 0.12!

How to solve this issue please?
Last edited on
Why don't you convert it to a string?
Here's a good web page to help understand why floating point numbers show up the way they do. Make sure you read the "Basic Answers" page.

http://floating-point-gui.de/

The point is, there is no such number as ".12" inside the computer, only a very close approximation. And counting the base-10 decimal points before you get all 0's is not exactly possible. As Thomas1965 suggested, you could write out the number without padding to some arbitrary precision (say 8 decimal places) and count the number of characters that are printed out. But there is nothing intrinsic to the number that will tell you how many decimal places there are, and you will always have to deal with rounding errors when converting to/from base-10.
Not sure how correct/portable this code is but it seems to work on cpp.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <limits>

int dec_places( double d )
{
    constexpr double precision{ 1e-7 };
    
    double temp{}; int decimal_places{};
    do {
        d *= 10;
        temp = d - int( d );
        
        decimal_places++;
    } while( temp > precision && decimal_places < std::numeric_limits<double>::digits10 );
    
    return decimal_places;
}

int main() 
{
    constexpr int size{ 6 };
    const double nums[size]{ 0.2, 0.254, 0.36847, 0.12, 3.1415, 1.0/3 };
    
    std::cout << "expected = { 1, 3, 5, 2, 4, ? }\n";
    std::cout << "actual = { ";
    for( int i{}; i < size; i++ ) {
        std::cout << dec_places( nums[i] );
        if( i != size - 1 ) std::cout << ", ";
    }
    std::cout << " }";
}


expected = { 1, 3, 5, 2, 4, ? }
actual = { 1, 3, 5, 2, 4, 15 } 
Last edited on
Topic archived. No new replies allowed.