Understanding Floating‑Point Precision and Common Pitfalls in Java
The article explains why comparing floating‑point numbers with == in Java often yields unexpected results, describes the IEEE‑754 representation of float and double, demonstrates common pitfalls through code examples, and provides step‑by‑step methods for converting decimal fractions to binary.
During Java interview screenings, a classic question is to predict the output of System.out.println( 1f == 0.999999999999f ); . Many candidates answer false or true , but the real purpose of the question is to expose how floating‑point numbers are computed, what to watch for when coding, and the typical pitfalls.
The interview guide emphasizes that primitive floating‑point types should never be compared with == , and wrapper types should not use equals . This rule is reinforced by a quotation from the Alibaba Java Development Manual.
Several surprising phenomena are demonstrated:
Condition checks that behave unexpectedly, e.g.: System.out.println( 1f == 0.9999999f ); // prints: false System.out.println( 1f == 0.99999999f ); // prints: true ?
Data conversion anomalies: float f = 1.1f; double d = (double) f; System.out.println(f); // prints: 1.1 System.out.println(d); // prints: 1.100000023841858 ?
Basic arithmetic giving unexpected results: System.out.println( 0.2 + 0.7 ); // prints: 0.8999999999999999 ?
Incrementing a large float value: float f2 = 84552631f; for (int i = 0; i < 10; i++) { System.out.println(f2); f2++; } // prints: 8.4552632E7 ? (repeated)
Because monetary calculations (order amount, product price, transaction value, etc.) demand high precision, using float or double can be risky and may cause serious bugs if not handled carefully.
The article then explains how computers store floating‑point numbers according to the IEEE‑754 standard, using a sign‑bit, exponent, and mantissa (fraction). For float , the exponent occupies 8 bits (range –127 ~ 128) and the mantissa 23 bits (≈ 6‑7 decimal digits). For double , the exponent occupies 11 bits (range –1023 ~ 1024) and the mantissa 52 bits (≈ 15‑16 decimal digits).
When a decimal fraction is converted to binary, the process involves separating the integer and fractional parts, converting the integer part with the usual division‑by‑2 method, and converting the fractional part with the “multiply‑by‑2 and take the integer” method.
Example 1: converting 0.875 to binary yields 0.111 . According to the IEEE‑754 layout for a float , the sign bit is 0 , the exponent is 126 (binary 01111110 ), and the mantissa is 11000000000000000000000 , giving the 32‑bit pattern 00111111011000000000000000000000 .
Example 2: converting 6.36 to binary results in 110.01011100… . Using a float , the sign bit is 0 , the exponent is 129 (binary 10000001 ), and the mantissa (truncated to 23 bits) is 10010111000010100011111 , producing the 32‑bit pattern 01000000110010111000010100011111 .
Both original values in the interview question share the same binary representation: 00111111 10000000 00000000 00000000 so the comparison returns true .
For readers who prefer not to perform manual conversion, the article recommends an online binary conversion tool (e.g., "binaryconvert") that can switch between bases instantly.
In summary, whenever business code involves floating‑point numbers, developers should be vigilant, understand the underlying IEEE‑754 representation, and consider alternative data types (such as BigDecimal ) for high‑precision monetary calculations.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.