0
#include <iostream>

int main()
{
    double number1 = 1.4999999999999999;
    double number2 = 1.499999999999999;

std::cout << "NUMBER 1 => ROUND (" << number1 << ") = " << round(number1) << std::endl;
std::cout << "NUMBER 2 => ROUND (" << number2 << ") = " << round(number2) << std::endl;

std::cin.get();
}

Output for above code is as follows: -

NUMBER 1 => ROUND (1.5) = 2

NUMBER 2 => ROUND (1.5) = 1

I am unclear how my number1 and number2 are changing to 1.5 and if so they're changing to 1.5 then why two different output's of round function for same number.

Tried using long double still same output

I am using Visual Studio 2019, will that make any difference?

  • 2
    Have you looked at how both numbers are represented? – user975989 Nov 15 '20 at 06:10
  • double will have precision issues with so many digits after the decimal point , use long double perhaps ? – Zarif Nov 15 '20 at 06:13
  • 1
    Look at the hex value of number1 and number2 and the reason will be quite apparent – doug Nov 15 '20 at 06:14
  • 1
    Add `std::cout.precision(17);` before printing to get a better idea of what value each number has. – dxiv Nov 15 '20 at 06:14
  • 1
    Perhaps [Is floating point math broken?](https://stackoverflow.com/q/588004/5987) can shed some light. – Mark Ransom Nov 15 '20 at 06:20
  • 2
    The reason is simple, in your computer (and most computers will be the same) `1.4999999999999999` equals `1.5`. Floating point numbers are **finite**, so for most numbers all you get is a approximation to the mathematically correct number. And clearly (not sure why you are doubting this) `1.499999999999999` is less than `1.5`. – john Nov 15 '20 at 06:33
  • This really has nothing to do with `round`. The issue involves converting literal values to floating-point values, i.e., it occurs in the initialization of `number1` and `number2`, not later when they are used. – Pete Becker Nov 15 '20 at 17:53

2 Answers2

4
#include <iostream>

int main()
{
    double number0 = 1.5;
    double number1 = 1.4999999999999999;
    double number2 = 1.499999999999999;
 
    std::cout << (number1 == number0) << " " << (number2 < number0) << std::endl;
}

The above outputs 1 1 on platforms that use IEEE-754 for representing floating points. In this case, number1 is stored as exactly 1.5 and gets rounded up to 2 while number2 has a value strictly less than 1.5 and gets rounded down to 1.

dxiv
  • 16,984
  • 2
  • 27
  • 49
  • I would add that representing a floating-point number on a machine is harder than most programmers know, as you said, the representation of `1.5` isn't exactly `1.5`, and thus, rounding errors may occur. (And a nice portion of ***any*** standard Numerical Analysis discusses about the floating-point representation). – Kerek Nov 15 '20 at 09:35
  • 3
    Actually, the representation of 1.5 *is* exact. It's 3 x 2^-1. 1.49, on the other hand, will be inexact. – Marshall Clow Nov 15 '20 at 15:08
2

On a machine using IEEE-754 floating point representation (i.e, most of the machines today). number1 is exactly the same as 1.5.

You can inspect the bit patterns using std::hexfloat:

#include <iostream>
#include <iomanip>

int main()
{
    double number1 = 1.4999999999999999;
    double number2 = 1.499999999999999;

    std::cout << std::hexfloat << number1 << " " << number2 << std::endl;
}

prints 0x1.8p+0 0x1.7fffffffffffbp+0

Marshall Clow
  • 15,972
  • 2
  • 29
  • 45
  • 1
    +1 for `hexfloat`. Or, writing it as exact decimals, the two numbers are stored as `1.5` [and](https://www.wolframalpha.com/input/?i=6755399441055739+%2F+2%5E52) `6755399441055739 / 2^52` `= 1.4999999999999988897769753748434595763683319091796875`. – dxiv Nov 15 '20 at 17:52