-9
float a = 4.2 ;
double b = 4.2 ;

if(a==b)
  cout<<"True";
else
  cout<<"False";

It will give result as "False" . But when I declare a and b as ,

float a = 4.5;
double b =4.5 ;

It gives the result "True"

What is happening here ? Can anybody explain it please and its not duplicate as values when given "4.5" or "4.0" it results in "True"

Bhavesh Kumar
  • 116
  • 1
  • 9

2 Answers2

1

A comparison between double and float gets float implicitly converted to double. Which means that your a==b is interpreted as (double) a == b.

The fractional part of 4.5 is an exact power of 2: 0.5 == 2-2. This value is represented in binary floating-point format precisely

4.5 dec = 100.1 bin

And it is represented precisely in both double and float. So, the comparison compares 4.5 to 4.5 and the result is true.

4.2 is requires an infinite periodic sum of powers of 2 to represent.

4.2 dec = 100.0011001100110011... bin = 100.(0011) bin

For this reason it is represented in double and float only approximately - the infinite sequence gets trimmed in one way or another. Since float has less precision than double, the value stored in float ends up being different than the value stored in double. In double you get something like 4.1999998092651367, while in float you get something like 4.2000000000000002. The conversion to double in (double) a == b cannot make the values to "match" and the result is false.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • what u mean by exact sum of powers of 2 ? what in the case of values to be "4.0" ? – Bhavesh Kumar Jul 29 '15 at 13:43
  • @Bhavesh Kumar: I'm talking about the fractional part specifically in this case. `0.5` is a power of `2` by itself. `0.2` is not. The whole part does not matter in this case (as long as it is small). You can repeat your experiments with `0.5` and `0.2` respectively and observe the same results. – AnT stands with Russia Jul 29 '15 at 13:47
  • why we check this with power of "2" , I mean it can be any else number though ? – Bhavesh Kumar Jul 29 '15 at 13:52
  • 1
    @Bhavesh Kumar: Floating-point numbers on most platforms are stored in IEEE754 formats, which are **binary** floating-point formats. All values are represents through sums of powers of `2`. If a value is representable as a *finite* sum of powers of `2`, then it is possible to represent it precisely (depends on the actual powers not being to spread to far apart). If a value requires an *infinitely long* sum of powers of `2`, then it cannot be represented precisely. That is exactly the difference between `4.5` and `4.2`. – AnT stands with Russia Jul 29 '15 at 13:57
  • `4.5` in binary is just `100.1`. `4.2` in binary is `100.0011001100110011...` and so on ad infinitum. See the difference? – AnT stands with Russia Jul 29 '15 at 13:59
  • thank you Sir , you cleared my doubt very well – Bhavesh Kumar Jul 29 '15 at 14:01
0

Floating point variables cannot accurately represent all values. In particular, the values 0.1 and 0.2 (in decimal) cannot be exactly represented, and only an approximation is stored in the variable.

A variable of type double will store such values to greater precision than will a float (i.e. it will give a better approximation). So the two values will not be equal.

To understand, understand that floating point variables typically work with base 2 (binary fractions). Then try to represent 1/10 (decimal) in base 2. The result is an infinite series. It is the same phenomenon that results in 1/3 being represented in decimal as 0.33333.... (an infinite number of digits). The only differences is that, in binary, a different set of values have an infinite number of digits. One of the affected values is 1/10.

Peter
  • 35,646
  • 4
  • 32
  • 74