Двойное приведение к Двойному меньше нуля - PullRequest
3 голосов
/ 22 октября 2008
Double out = otherTypes.someMethod(c, c2);
assertEquals((Double)-1.0D, out);

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

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

Ответы [ 5 ]

6 голосов
/ 22 октября 2008

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

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

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

в вашем коде.

Вы можете найти больше об уловках и ловушках числа с плавающей точкой, например, в одной из статей Брайана Гетца: «Где твоя точка?»

2 голосов
/ 22 октября 2008

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

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

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

1 голос
/ 23 октября 2008

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

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

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

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

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

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

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

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

0 голосов
/ 22 октября 2008

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

assertEquals(Double.class.cast(-1.0D), out);
0 голосов
/ 22 октября 2008

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

assertEquals(Double.doubleToLongBits(-1.0), Double.doubleToLongBits(out));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...