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
.