7

If i write code in c++:

long long d = 999999998.9999999994;
cout<<d;

I get output: 999999999 (rounding up)

But output of this code:

long long d = 999999998.9999994994;
cout<<d;

is 999999998 (rounding down)

Is it something to do with precision. Is there any way i can change precision. floor() function also gives the same output.

I also noticed that if i assign value 8.9999994994 or 8.9999999994 to d(above variable). Output is 8.

pirate
  • 496
  • 6
  • 16
  • You can explicitly add 0.5 and cast double to long long. – Oleksandr Verhun Oct 04 '14 at 19:42
  • C++11 support? User defined literals could help. – Yakk - Adam Nevraumont Oct 04 '14 at 20:52
  • @OleksandrVerhun You can do this, but if your goal is to round the floating-point number to the nearest integer, you shouldn't do this. https://www.frama-c.com/floating-point/2013/05/02/Harder-than-it-looks-rounding-float-to-nearest-integer-part-1.html – Pascal Cuoq Oct 04 '14 at 21:03
  • @OleksandrVerhun If you really have to round to nearest integer, please use lrint() family of functions. They are POSIX and C99, supported by glibc and Visual Studio 2013. http://linux.die.net/man/3/lrint – Severin Pappadeux Dec 15 '14 at 03:53

2 Answers2

11

999999998.9999999994 is not exactly representable in double, so the actual value is one of the two representable numbers on either side of 999999998.9999999994 - either 999999998.99999988079071044921875 or 999999999 (assuming IEEE-754 binary64 format), selected in an implementation-defined manner. Most systems will by default round to nearest, producing 999999999.

The net result is that on those systems when you write 999999998.9999999994 it ends up having the exact same effect as writing 999999999.0. Hence the subsequent conversion yields 999999999 - the conversion from a floating point number to an integer always truncates, but here there is nothing to truncate.

With 999999998.9999994994, the closest representable numbers are 999999998.999999523162841796875 and 999999998.99999940395355224609375. Either one produces 999999998 after truncation. Similarly, with 8.9999999994, the closest representable numbers are 8.999999999399999950355777400545775890350341796875 and 8.9999999994000017267126168007962405681610107421875, and either one will produce 8 after truncation.

T.C.
  • 133,968
  • 17
  • 288
  • 421
4
long long d = 999999998.9999999994; 

The closest value to 999999998.9999999994 that double can represent is 999999999.0 - remember that floating points have finite precision ;).
Therefore, truncating the decimal places yields 999999999, and thats what is saved in d.

Using a literal with L-suffix does indeed lead to 999999998 being saved in d - long double has a higher precision.

long long d = 999999998.9999994994;

The closest value to 999999998.9999994994 that double can represent is actually below 999999999 - approximately 999999998.999999523 on my machine. Truncating the decimal places subsequently yields 999999998, and that is stored in d.

Columbo
  • 60,038
  • 8
  • 155
  • 203