Backend Development 9 min read

Understanding Java Float -0.0 and hashCode: Why 0.0 and -0.0 Behave Differently in Maps

This article explains why Java's Float values 0.0 and -0.0 have different hashCode results, how that affects their use as Map keys, and demonstrates the underlying IEEE‑754 representation and related debugging steps with concrete code examples.

Top Architect
Top Architect
Top Architect
Understanding Java Float -0.0 and hashCode: Why 0.0 and -0.0 Behave Differently in Maps

The author encountered a puzzling case while solving the LeetCode‑style problem "max‑points‑on‑a‑line" in Java: points that should lie on the same line were counted incorrectly because the map used Float slopes as keys, and the values 0.0f and -0.0f produced different hash codes.

Initial code snippet:

import java.util.HashMap;
import java.util.Map;

public class Solution {
    public int maxPoints(Point[] points) {
        if (points.length <= 2) {
            return points.length;
        }
        int max = 2;
        for (int i = 0; i < points.length - 1; i++) {
            Map<Float, Integer> map = new HashMap<>(16);
            int ver = 0, cur, dup = 0;
            for (int j = i + 1; j < points.length; j++) {
                if (points[j].x == points[i].x) {
                    if (points[j].y != points[i].y) {
                        ver++;
                    } else {
                        dup++;
                    }
                } else {
                    float d = (float) ((points[j].y - points[i].y) / (double) (points[j].x - points[i].x));
                    map.put(d, map.get(d) == null ? 1 : map.get(d) + 1);
                }
            }
            cur = ver;
            for (int v : map.values()) {
                cur = Math.max(v, cur);
            }
            max = Math.max(max, cur + dup + 1);
        }
        return max;
    }
}

Running a test with points (2,3), (3,3), (-5,3) produced a result of 2 because the slopes (3‑3)/(3‑2) = 0.0 and (3‑3)/(-5‑2) = -0.0 were treated as different keys. Debugging showed that 0.0 == -0.0 evaluates to true, but their hash codes differ.

System.out.println(0.0 == -0.0); // true
System.out.println(new Float(0.0).hashCode() == new Float(-0.0).hashCode()); // false

The discrepancy originates from Float.hashCode() , which ultimately calls Float.floatToIntBits() . According to the IEEE‑754 standard, +0.0 and -0.0 have distinct bit patterns (0x00000000 vs 0x80000000), so their integer representations – and thus hash codes – differ.

public static int floatToIntBits(float value) {
    int result = floatToRawIntBits(value);
    if (((result & FloatConsts.EXP_BIT_MASK) == FloatConsts.EXP_BIT_MASK) &&
        (result & FloatConsts.SIGNIF_BIT_MASK) != 0)
        result = 0x7fc00000; // canonical NaN
    return result;
}

Because Float.equals() also compares the raw bits, 0.0f and -0.0f are considered unequal, reinforcing the conclusion that using floating‑point numbers as map keys is unsafe.

The article concludes that Java floating‑point semantics follow IEEE‑754, which defines positive/negative zero, infinities, and NaN. These edge cases can cause unexpected behavior in collections, so developers should avoid using Float/Double as keys or employ a more robust representation such as the line equation Ax+By+C=0.

Finally, the author provides a short checklist of the key take‑aways and warns against relying on floating‑point values for hash‑based structures.

Javaieee754floatHashCodemap-keynegative-zero
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.