4.5
and 4.05
are double
literals. You assign them to a float
, which requires a possibly lossy conversion (rounding), then compare them to the same literal again, which promotes the float
to a double
. This second conversion is always exact, but it can't undo rounding errors that happened during the first double->float conversion.
(double)(float)4.5
equals 4.5
, because of the internal representation of binary floating point: 4.5 = 9 / 2 = 9 * 2-1. This is represented exactly by both float and double.
(double)(float)4.05
does not equal 4.05
because 4.05 can not be represented exactly in base 2 (with a finite number of digits): It's 405/10 = 405 * 2-1 * 5-1. The 5-1 factor is periodic in base 2. So when representing 4.05 as float or double, it is rounded to as many bits as the respective type can hold (24 bit for float, 53 for double), which of course results in different numbers (try rounding 2/3 to four two decimal digits and to six decimal digits).