Floating Point Comparison Puzzle
Consider the following C code:
int main() { float a = 0.7; float b = 0.5; if (a < 0.7) { if (b < 0.5) printf("2 are right"); else printf("1 is right"); } else printf("0 are right"); }
You would intuitively expect the output to be "0 are right." However, the surprising result is "1 is right." Why does this occur?
The Pitfalls of Floating-Point Comparison
The key lies in the differences between floating-point and double-precision numbers in C. In the code, the variables a and b are declared as floats, which are 32-bit floating-point numbers. However, both comparisons (a < 0.7 and b < 0.5) involve doubles, as the literals 0.7 and 0.5 are treated as doubles.
During the comparison, the float variables get promoted to doubles, allowing for a higher range and precision. However, this conversion can introduce subtle artifacts due to the limited precision of floats. In this case, 0.7 as a float is not exactly equivalent to 0.7 as a double.
Specifically, 0.7 as a float is represented as 0x3f000000 in the IEEE 754 standard. When promoted to a double, this value is not an exact representation of 0.7. Instead, it becomes slightly greater, around 0x3f00000000000000 (approximately 0.7000000000000001).
The Cause of the Unexpected Result
As a result of this promotion, the condition a < 0.7 becomes true because the double representation of a is marginally less than 0.7. Subsequently, the second comparison b < 0.5 evaluates to false because b (represented exactly as a double) is equal to 0.5. Thus, the code prints "1 is right."
Solutions
To resolve this issue, you can either:
The above is the detailed content of Why does comparing floats to double literals in C produce unexpected results?. For more information, please follow other related articles on the PHP Chinese website!