2008-10-22 3 views
3
Double out = otherTypes.someMethod(c, c2); 
assertEquals((Double)-1.0D, out); 

Я получаю сообщение об ошибке «Двойной не может быть разрешен» (Double in assertEquals), есть ли способ взломать его, кроме извлечения переменной?Double cast for Double меньше нуля

Эта ошибка на Java или просто очень полезная функция, которая не будет исправлена?

+0

Причина, по которой это не работает, заключается в том, что она пытается вычесть 1.0D из «Double», который не может быть разрешен. – Epaga 2008-10-22 06:46:38

ответ

2

Моя вариация похожа на

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

это большая разница jjnguy является Double.valueOf может возвращено сохраненную копию вместо того, чтобы создать новый объект.

6

Одно важное замечание: из-за того, как работают числа с плавающей запятой, вы никогда не должны сравнивать два удвоенных номера (или числа с плавающей запятой в целом) для прямого равенства, всегда сравнивать, если их разность находится в указанной дельте: abs(double1 - double2) < delta.

JUnit имеет способ assertEquals(double expected, double actual, double delta), чтобы сделать именно это. Тем не менее, вы должны, вероятно, использовать что-то вроде

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

в вашем коде.

Вы можете найти больше трюков и ловушек с плавающей запятой в, например, в одной из статей Брайан Гетц: "Where's your point?"

+0

Никогда? Бывают случаи, когда вы ожидаете, что метод вернет определенное двойное значение. – 2008-10-22 15:10:08

0

Мое предложение, если вы хотите, чтобы проверить, если два двойников точно так же:

assertEquals(Double.doubleToLongBits(-1.0), Double.doubleToLongBits(out)); 
0

Это идет через компилятор:

assertEquals(Double.class.cast(-1.0D), out); 
1

чтобы преобразовать -1.0D в Double, лучший способ нас обычно использовать Double.valueOf (-1.0D) , Класс Double кэширует результаты вызовов valueOf, чтобы вы не всегда создавали новый объект в куче. Но еще лучше - конвертировать в двойной, что дешевле. Используйте out.doubleValue(), чтобы получить значение как двойное. Единственное предостережение заключается в том, что это может быть null, что является отдельным случаем, который, вероятно, стоит обнаружить сам по себе.

Вы также должны быть осторожны с неточностями с плавающей запятой при проверке прямого равенства таким образом. Два числа, которые теоретически равны, могут не иметь представлений, которые в точности равны, поскольку в большинстве операций с плавающей запятой имеется некоторая ошибка округления. Простое решение, которое будет работать в этом случае, чтобы проверить, если разность меньше некоторой дельта:

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

Вы также можете использовать удобный метод JUnit для делать именно это:

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

Используйте очень небольшое значение для delta, например 10E-10, или что-то подходящее для вашего приложения. В самом общем случае, если вы не знаете диапазон значений вы сравниваете, вы должны умножить дельту относительного размером каждого числа, например:

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

Если вы сравнивая очень большие цифры, вы хотите, чтобы разрешенная дельта была больше, и если вы сравниваете очень маленькие числа, вы хотите, чтобы разрешенная дельта была меньше. Но для вашего случая вы заранее знаете один из своих параметров, поэтому можете просто перекодировать дельта.