On Doubles and Equality

2020-02-13 01:37发布

问题:

One of the methods i have returns a double. When testing this method as part of my jUnit, i noticed the following oddity:

    String a = "someString";
    String b = "someDifferentString";

    double result = c.getScore(a, b, true);
    System.out.println(result); // prints 0.0

    assert (result > 0.0); // Test passes

So .. I ask you, how can 0.0 be more then 0.0? Why does result > 0.0 evaluates to true?

回答1:

assert is a Java keyword. You need assertTrue(result > 0.0)



回答2:

Comparing doubles in general is dangerous, because floating-point representations are, by definition, inexact. Furthermore, you have to be careful when printing values out, as the printed representation is often rounded compared to the actual stored representation.

That said, @JBNizet nailed it -- you're writing a Java assertion, not a JUnit test!



回答3:

It's floating point math that is your worry. 0.0 is probably not absolute 0.0, but 0.00000000000000009 or something really really small. Why is this? Well floating point math is discrete in computers. But in reality floating point math is continuous, and hence we have a mismatch between discrete (digital) and continuous (analog). Errors begin to creep in causing things to drift a little. If you want to know more read this:

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

There are methods in junit specifically designed for comparing floats/doubles that allow for a tolerance (ie assertEquals(double expected,double actual,double epsilon)). Use those and you should stabilize your test in the face of the tiny errors you're seeing. Be aware not to set them too high because your overall error should be very small.

See this question about it as well:

JUnit assertEquals(double expected, double actual, double epsilon)