Floating-point arithmetic represents values with finite precision, so computations can preserve a broad numeric range while losing distinctions through rounding. Java also distinguishes +0.0 and -0.0 internally: primitive == treats them as equal, but boxed values, collections, and records can expose the difference. section 4.15.1 section 4.6
Avoid common floating-point failures by:
- Checking whether implicit widening can round large integers; int-to-float and long-to-float lose precision from about 2^24, while long-to-double can lose precision from about 2^53. section 4.6
- Using double instead of float unless reduced performance or memory usage is specifically justified, and choosing BigDecimal when controllable precision matters more. section 4.16
- Making division intent explicit: use 2.0 or a cast when the fractional result is required, and avoid var for primitive arithmetic whose intended type matters. section 4.3
- Normalizing signed zero before storing values in fields or collections when +0.0 and -0.0 should represent one value. section 4.15.1
A widening conversion can erase a distinction
A long value of 2^53 and that value plus one are different integers, but converting both to double can make them compare equal because the floating-point representation rounds away the final increment. An explicit cast makes the conversion visible; it does not restore the lost precision. section 4.6
long longVal = 1L << 53; double doubleVal = longVal; double doubleValPlusOne = longVal + 1; System.out.println(doubleVal == doubleValPlusOne); #1
Inspect the minimal Java example showing two distinct long values becoming equal after conversion to double. section 4.6



















