0

I'm a newbie in C++. I got trouble when count the decimal part by C++, here is the example and code:

example:

   3.01: count of decimal part is 2
103.939: count of decimal part is 3

code:

int result = 0;
double d   = 4.01;

while(true) {
    cout << "(int)d: " << (int)d << endl;
    if(d == (int)d) break;

    d *= 10;
    cout << "d *= 10: " << d << endl;

    result++;
}
cout << result << endl;

console:

int(d): 4
d *= 10: 40.1
int(d): 40
d *= 401
int(d): 400
d *= 10: 4010
int(d): 4009
...

what happens to 4.01? And the same strange result when the double = 5.01 etc. I know it's the problem of precision when convert DOUBLE to INT, but I'm really curious about how it happens when the test doubles like 4.01, 5.01, etc.

And in addition, how to modify the if state correct to test 4.01?

Pritom Sarkar
  • 2,154
  • 3
  • 11
  • 26
frank jorsn
  • 489
  • 1
  • 9
  • 27
  • 3
    When you do `double d = 4.01;`, the value of `d` is not 4.01. It's a number very close to 4.01. Important reading: https://stackoverflow.com/questions/588004/is-floating-point-math-broken – aschepler Feb 22 '21 at 05:49
  • Hint. The closest `double` to `4.01` is `4.0099999999999997868371792719699442386627197265625`. Nothing particularly strange here. After all, most folk are happy with the fact that the closest `int` to `4.01` is `4`. One way round this is to round your number to 14 significant figures, and output only those digits, writing something clever to not print trailing zeros. – Bathsheba Feb 22 '21 at 07:09
  • Got it! Guys! Thanks! – frank jorsn Feb 22 '21 at 07:12

2 Answers2

3

Since your question has been answered in the comments, I am posting a different approach to count decimal digits ( by taking input as string and treating the entire thing as string operation ).

#include <iostream>

using namespace std;

int main()
{
    string d;
    cin>>d;
    
    int flag=0, count=0, pos;
    
    for(int i = 0 ; i < d.length() ; i++){
        if(d[i]=='.'){
            flag = 1; 
            pos = i;  // for keeping the index of decimal point
            continue;
        }
        
        if(flag==1){
            count++;
        }
        
    }
    

    // for removing trailing zeroes like 0.10000 is actually 0.1
    if(flag==1){
        for(int i=d.length()-1;i>pos;i--){
            
            if(d[i]!='0'){
                break;
            }
            
            if(d[i]=='0'){
                count--;
            }
            
        }
    }
    
    cout<<count<<"\n";

    return 0;
}

UPD 1.0 : Taken input as double as asked by frank.

#include <iostream>

using namespace std;

int main()
{
    
    double num;
    
    string d;
    cin>>num;
    
    d = to_string(num);
    
    int flag=0, count=0, pos;
    
    for(int i = 0 ; i < d.length() ; i++){
        if(d[i]=='.'){
            flag = 1; 
            pos = i;  // for keeping the index of decimal point
            continue;
        }
        
        if(flag==1){
            count++;
        }
        
    }
    

    // for removing trailing zeroes like 0.10000 is actually 0.1
    if(flag==1){
        for(int i=d.length()-1;i>pos;i--){
            
            if(d[i]!='0'){
                break;
            }
            
            if(d[i]=='0'){
                count--;
            }
            
        }
    }
    
    cout<<count<<"\n";

    return 0;
}
KL_KISNE_DEKHA_HAI
  • 649
  • 11
  • 26
0

Check this code out. It worked for me.

int result = 0;
int f = 1;
double d = 4.01;
while((int)(d*f)!=d*f)
{
    f*=10;
    result++;
}
std::cout<<result;

Output:

2
kdcode
  • 524
  • 2
  • 7