16

What is an elegant, readable and non-verbose way of comparing two floating point value for exact equality?

As simple as it may sound, its a wicked problem. The == operator doesn't get the job done for NaN and also has special treatment for zero:

(+0.0 == -0.0) -> true
Double.NaN == Double.NaN -> false

But I want to determine if two values are exactly the same (but I do not care for different NaN patterns, so any NaN == any other NaN -> true).

I can do this with this ugly Monster piece of code:

Double.doubleToLongBits(a) == Double.doubleToLongBits(b)

Is there a better way to write this (and make the intent obvious)?

4

2 回答 2

23

You can use

Double.compare(a, b) == 0

From the javadoc for compareTo

  • Double.NaN is considered by this method to be equal to itself and greater than all other double values (including Double.POSITIVE_INFINITY).
  • 0.0d is considered by this method to be greater than -0.0d.
于 2013-03-22T14:24:03.660 回答
10

What you've got is already the best way of doing it, I'd say. It makes it clear that you're interested in the bitwise representation of the value. You happen to be converting those bits to long as a convenient 64-bit type which doesn't have any funky behaviour.

If you don't want it appearing frequently in your codebase, just add a method to wrap it:

public static boolean bitwiseEqualsWithCanonicalNaN(double x, double y) {
    return Double.doubleToLongBits(x) == Double.doubleToLongBits(y);
}

Note that as per your question, this does not differentiate between different NaN values. If you wanted to do this at a later date, you'd need to use Double.toRawLongBits.

于 2013-03-22T14:24:55.680 回答