#include <stdio.h>
int main(void){
float a = 1.1;
double b = 1.1;
if(a == b){
printf("if block");
}
else{
printf("else block");
}
return 0;
}
Prints: else block
#include <stdio.h>
int main(void){
float a = 1.5;
double b = 1.5;
if(a == b){
printf("if block");
}
else{
printf("else block");
}
return 0;
}
Prints: if block
What is the logic behind this?
Compiler used: gcc-4.3.4
The exact value of 1.1 decimal in binary is non-ending fraction 1.00011001100110011001100(1100).... The double constant
1.1
is 53-bit truncation / approximate value of that mantissa. Now this when converted to float, the mantissa will be represented just in 24 bits.When the
float
is converted back to double, the mantissa is now back to 53 bits, but all memory of the digits beyond 24 are lost - the value is zero-extended, and now you're comparing (for example, depending on the rounding behaviour)and
Now, if you used 1.5 instead of 1.1;
1.5 decimal is exactly 1.1 in binary. It can be presented exactly in just 2 bit mantissa, therefore even the 24 bits of float are an exaggeration... what you have is
and
The latter, zero extended to a double would be
which clearly is the same number.
This is because
1.1
is not exactly representable in binary floating-point. But1.5
is.As a result, the
float
anddouble
representations will hold slightly different values of1.1
.Here is exactly the difference when written out as binary floating-point:
Thus, when you compare them (and the
float
version gets promoted), they will not be equal.Must read: What Every Computer Scientist Should Know About Floating-Point Arithmetic