Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why comparing double and float leads to unexpected result? [duplicate]

Tags:

c++

visual-c++

Possible Duplicate:
strange output in comparision of float with float literal

float f = 1.1;
double d = 1.1;
if(f == d) // returns false!

Why is it so?

like image 222
Suri Avatar asked Jul 17 '11 06:07

Suri


People also ask

Why is it a problem to compare two floating point numbers?

Comparing for equality Floating point math is not exact. Simple values like 0.1 cannot be precisely represented using binary floating point numbers, and the limited precision of floating point numbers means that slight changes in the order of operations or the precision of intermediates can change the result.

Why should you be careful when using float and double values?

Let's explore this problem with the help of an example: All floating point values that can represent a currency amount (in dollars and cents) cannot be stored exactly as it is in the memory. So, if we want to store 0.1 dollars (10 cents), float/double can not store it as it is.

What happens when float and double is added?

To answer your question, you can add a float to a double and vice versa. Generally, the result will be made into a double , and you will have to cast it back to a float if that is what you want.

Can you compare float and double?

float has 7 decimal digits of precision. double is a 64-bit IEEE 754 double precision Floating Point Number – 1 bit for the sign, 11 bits for the exponent, and 52* bits for the value. double has 15 decimal digits of precision.


2 Answers

The important factors under consideration with float or double numbers are:
Precision & Rounding


Precision:
The precision of a floating point number is how many digits it can represent without losing any information it contains.

Consider the fraction 1/3. The decimal representation of this number is 0.33333333333333… with 3′s going out to infinity. An infinite length number would require infinite memory to be depicted with exact precision, but float or double data types typically only have 4 or 8 bytes. Thus Floating point & double numbers can only store a certain number of digits, and the rest are bound to get lost. Thus, there is no definite accurate way of representing float or double numbers with numbers that require more precision than the variables can hold.


Rounding:
There is a non-obvious differences between binary and decimal (base 10) numbers.
Consider the fraction 1/10. In decimal, this can be easily represented as 0.1, and 0.1 can be thought of as an easily representable number. However, in binary, 0.1 is represented by the infinite sequence: 0.00011001100110011…

An example:

#include <iomanip>
int main()
{
    using namespace std;
    cout << setprecision(17);
    double dValue = 0.1;
    cout << dValue << endl;
}

This output is:

0.10000000000000001

And not

0.1.

This is because the double had to truncate the approximation due to it’s limited memory, which results in a number that is not exactly 0.1. Such an scenario is called a Rounding error.


Whenever comparing two close float and double numbers such rounding errors kick in and eventually the comparison yields incorrect results and this is the reason you should never compare floating point numbers or double using ==.

The best you can do is to take their difference and check if it is less than an epsilon.

abs(x - y) < epsilon
like image 185
Alok Save Avatar answered Oct 23 '22 00:10

Alok Save


Try running this code, the results will make the reason obvious.

#include <iomanip>
#include <iostream>

int main()
{
  std::cout << std::setprecision(100) << (double)1.1 << std::endl;
  std::cout << std::setprecision(100) << (float)1.1 << std::endl;
  std::cout << std::setprecision(100) << (double)((float)1.1) << std::endl;
}

The output:

1.100000000000000088817841970012523233890533447265625
1.10000002384185791015625
1.10000002384185791015625

Neither float nor double can represent 1.1 accurately. When you try to do the comparison the float number is implicitly upconverted to a double. The double data type can accurately represent the contents of the float, so the comparison yields false.

like image 30
Praetorian Avatar answered Oct 23 '22 01:10

Praetorian