tags:

views:

697

answers:

5
Double out = otherTypes.someMethod(c, c2);
assertEquals((Double)-1.0D, out);

I get error "Double cannot be resolved" (the Double in assertEquals), is there any way to hack around it except extracting variable?

Is this bug in Java or just very usefull feature that wont be fix?

+2  A: 

My variation is similar to jjnguy's

assertEquals(Double.valueOf(-1.0D), out)

This biggest difference is Double.valueOf can returned a cached copy rather than having to create a new object.

Johann Zacharee
+6  A: 

One important note: Because of the way floating point numbers work, you should never compare two doubles (or floating point numbers generally spoken) for equality directly, always compare if their difference is within a specified delta: abs(double1 - double2) < delta.

JUnit has an assertEquals(double expected, double actual, double delta) method to do exactly that. That said, you should probably use something like

assertEquals(-1.0d, (double) out, 0.000001d)

in your code.

You can find more on the tricks and traps of floating point number in for example in one of Brian Goetz's articles: "Where's your point?"

WMR
Never? There are cases where you expect a method to return a specific double value.
Dave L.
Never. If you do so anyways be prepared that stuff like `(28.0*0.01*100.0 == 28.0)` evaluates to `false`. Try it... If you need exact results, doubles or floats are not what you want. You might want to have a look at `BigDecimal`, which gives you complete control over precision and rounding.
WMR
You can never get a specific double value. As WMR says, have a look at the BigDecimal class. Especially look at the BigDecimal Javadoc for its double constructor, which points out why 0.1 is really not.
MetroidFan2002
I agree that usually you just want to check ranges, but "Never" is a bit of an overbroad generalization. There are certain exact double values that have special significance, such as NaN, positive and negative zeros and infinity.
Dave L.
Agreed, if you really need to check for these special values, you can check for equality. But for all other cases ("normal" numbers) ranges are what you want.
WMR
A: 

My suggestion when you want to check if two doubles are exactly the same:

assertEquals(Double.doubleToLongBits(-1.0), Double.doubleToLongBits(out));
jassuncao
A: 

This goes through the compiler:

assertEquals(Double.class.cast(-1.0D), out);
Hemal Pandya
+1  A: 

To convert -1.0D to a Double, the best way us usually to use Double.valueOf(-1.0D). The Double class caches the results of calls to valueOf so that you won't always be creating a new object on the heap. But even better is to convert out to a double, which is cheaper. Use out.doubleValue() to get the value as a double. The only caveat is that out might be null, which is a separate case that is probably worth detecting in its own right.

You should also be wary of floating-point inaccuracies when testing direct equality this way. Two numbers that are theoretically equal may not have representations that are exactly equal because there is some rounding error introduced with most floating-point operations. A simple solution that would work in this case is to test if the difference is less than some delta:

assertTrue(Math.abs(-1.0D-out.doubleValue()) < delta);

You can also use JUnit's convenience method for doing just this:

assertEquals(-1.0d, out.doubleValue(), delta);

Use a very small value for delta, like 10E-10, or something appropriate for your application. In the most general case, if you don't know the range of the values you're comparing, you need to multiply the delta by the relative size of each number, like so:

double tDelta = delta*(Math.abs(-1.0D)+Math.abs(out.doubleValue()));
assertEquals(-1.0d, out.doubleValue(), tDelta);

If you're comparing very huge numbers, you want the allowed delta to be larger, and if you're comparing very small numbers you want the allowed delta to be smaller. But for your case you know one of your parameters beforehand, so you can just hard-code the delta.

Sam