3

Why does this behaviour happen? that decimal after 6th place are incremented to next one in double but not increment when converted to int.

It is causing issues when converting to int, because despite printing 3, d1 still converts to 2 when converting to integer and not 3

    double d1 = 2.999999; //6 digits after decimal
    double d2 = 2.777777;
    
    double d3 = 2.77777;  //5 digits after decimal
    double d4 = 2.99999;  
    
    cout<<d1<<endl;       //gives 3
    cout<<(int)d1<<endl;  //still gives 2 not 3
    cout<<d2<<endl;       //gives 2.777778
    
    cout<<d3<<endl;       //gives 2.77777 as expected
    cout<<d4<<endl;       //gives 2.99999 as expected

I am assuming that it has to do something with compilers or precision but i am not sure of this unexpected behaviour. Kindly help

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • it has nothing to do with C++. There are no no defined floating-point formats in C++ and an implementation can use IEEE-754 or whatever. But the rounding when printing is definitely specified, and the precision is also 6 by default, therefore obviously printing 2.77777 are very different from 2.777777 – phuclv Jan 12 '23 at 05:42
  • No incrementing is happening here. When the value is displayed as `3`, that **does not mean** that the value has changed. It is **just** what has been determined by the program, as the right way to display the value. – Karl Knechtel Jan 12 '23 at 05:42
  • The [default behavior](https://stackoverflow.com/questions/66712807/default-precision-of-double-in-c?noredirect=1&lq=1) of `std::cout` is that it will print doubles with 6 digits of precision. It doesn't change the value of `d1`, but it rounds it off when displaying it. – Nathan Pierson Jan 12 '23 at 05:42
  • Does this answer your question? [How do I print a double value with full precision using cout?](https://stackoverflow.com/questions/554063/how-do-i-print-a-double-value-with-full-precision-using-cout) – Karl Knechtel Jan 12 '23 at 05:44
  • 1
    The fundamental issue here, I think, is that when you print a floating-point number, by default it is *rounded* to a certain number of significant digits (which by the way is not the same as "digits past the decimal"). Unless you change it, the default number of significant digits is 6. So that's why 2.999999 (with seven significant digits) was rounded, and the correctly-rounded value is 3. When you cast that number to `(int)`, however, that conversion simply throws away the fractional part, giving you 2. – Steve Summit Jan 12 '23 at 13:13
  • 1
    Also you should be aware that all of this talk about "significant digits" or "places past the decimal" applies only when we're printing numbers out, in decimal, for humans to read! Internally, floating-point numbers are typically represented in binary, base 2, and they don't actually have any decimal digits at all. – Steve Summit Jan 12 '23 at 13:14

1 Answers1

5

It's because the default precision of cout is 6. The compiler recognizes the all values exactly enough, but the output is rounded to 6 decimal places. If you want the exact result, you can change the code like this:

cout << setprecision(7);
double d1 = 2.999999; //6 digits after decimal
double d2 = 2.777777;

double d3 = 2.77777;  //5 digits after decimal
double d4 = 2.99999;  

cout<<d1<<endl;       //gives 2.999999
cout<<(int)d1<<endl;  //still gives 2 not 3
cout<<d2<<endl;       //gives 2.777777

cout<<d3<<endl;       //gives 2.77777 as expected
cout<<d4<<endl;       //gives 2.99999 as expected
Melvin Lang
  • 199
  • 1
  • 1
  • 14
  • 1
    Also, you don't get the "exact" result by setting the precision to 7; you get the result that you expect, but `2.777777` cannot be represented exactly in IEEE floating-point formats, so what you get is the **nearest approximation** to the stored value. – Pete Becker Jan 12 '23 at 14:54