liveBook · Manning

Floating-point arithmetic

As explained in 100 Java Mistakes and How to Avoid Them

A floating-point number is a numerical value represented with a significand and an exponent, allowing fractional values and a wide range of magnitudes with finite precision.

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

How 100 Java Mistakes and How to Avoid Them covers it

How deep it goes
Explains concrete failure modes and prevention rules, but stops short of a general floating-point representation treatment.
Examples
Uses signed-zero multiplication, boxed equality, set contents, integer widening, and integer division snippets.
What it assumes
Assumes familiarity with Java primitive types, arithmetic expressions, assignments, equality, and basic collections.
What you can do after
Diagnose precision loss and signed-zero surprises, then select explicit conversions, normalization, or higher-precision types.
How it connects
Connects floating-point arithmetic with IEEE 754, primitive widening, integer division, boxing, collections, records, and BigDecimal.

Also explained in

Compare how 20 books explain floating-point arithmetic →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Java Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.