gandalf34
gandalf34

Reputation: 49

double variables in c++ are showing equal even when they are not

I just wrote the following code in C++:

double variable1;
double variable2;
variable1=numeric_limits<double>::max()-50;
variable2=variable1;
variable1=variable1+5;
cout<<"\nVariable1==Variable2 ? "<<(variable1==variable2);

The answer to the cout statement comes out 1, even when variable2 and variable1 are not equal.Can someone help me with this? Why is this happening?

I knew the concept of imprecise floating point math but didn't think this would happen with comparing two doubles directly. Also I am getting the same resuklt when I replace variable1 with:

double variable1=(numeric_limits<double>::max()-10000000000000);

The comparison still shows them as equal. How much would I have to subtract to see them start differing?

Upvotes: 4

Views: 1928

Answers (6)

Alexandre C.
Alexandre C.

Reputation: 56956

From the C++03 standard:

3.9.1/ [...] The value representation of floating-point types is implementation-defined

and

5/ [...] If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined, unless such an expression is a constant expression (5.19), in which case the program is ill-formed.

and

18.2.1.2.4/ (about numeric_limits<T>::max()) Maximum finite value.

This implies that once you add something to std::numeric_limits<T>::max(), the behavior of the program is implementation defined if T is floating point, perfectly defined if T is an unsigned type, and undefined otherwise.

If you happen to have std::numeric_limits<T>::is_iec559 == true, in this case the behavior is defined by IEEE 754. I don't have it handy, so I cannot tell whether variable1 is finite or infinite in this case. It seems (according to some lecture notes on IEEE 754 on the internet) that it depends on the rounding mode..

Upvotes: 0

user195488
user195488

Reputation:

You should read the floating point comparison guide. In short, here are some examples:

float a = 0.15 + 0.15
float b = 0.1 + 0.2
if(a == b) // can be false!
if(a >= b) // can also be false!

The comparison with an epsilon value is what most people do.

#define EPSILON 0.00000001

bool AreSame(double a, double b)
{
    return fabs(a - b) < EPSILON;
}

In your case, that max value is REALLY big. Adding or subtracting 50 does nothing. Thus they look the same because of the size of the number. See @RichieHindle's answer.

Here are some additional resources for research.

Upvotes: 0

Armen Tsirunyan
Armen Tsirunyan

Reputation: 133004

numeric_limits<double>::max()

is a huuuuuge number. But the greater the absolute value of a double, the smaller is its precision. Apparently in this case max-50and max-5 are indistinguishable from double's point of view.

Upvotes: 2

RichieHindle
RichieHindle

Reputation: 281485

There isn't enough precision in a double to differentiate between M and M-45 where M is the largest value that can be represented by a double.

Imagine you're counting atoms to the nearest million. "123,456 million atoms" plus 1 atom is still "123,456 million atoms" because there's no space in the "millions" counting system for the 1 extra atom to make any difference.

Upvotes: 3

slaphappy
slaphappy

Reputation: 6999

The maximum value for a double is 1.7976931348623157E+308. Due to lack of precision, adding and removing small values such as 50 and 5 does not actually changes the values of the variable. Thus they stay the same.

Upvotes: 11

Related Questions