2016-08-30 2 views
-1

в приложении Java У меня есть модульный тест, который содержит следующую ситуацию:Почему это сравнение между 2 BigDecimal не удается?

BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal(2.85000); 
BigDecimal rendimentoLordoProvvisiorioDB = null; 

rendimentoLordoProvvisiorioDB = pucManager.getRendimentoLordoProvvisorio(date); 

assertTrue(rendimentoLordoProvvisiorioExpected.compareTo(rendimentoLordoProvvisiorioDB) == 0); 

значения rendimentoLordoProvvisiorioExpected переменных вручную выставиться к 2.85000 и полученное значение rendimentoLordoProvvisiorioDB является 2,85000 ,

Проблема заключается в том, что, когда я делаю это Comparision в assertTrue() функция JUnit

assertTrue(rendimentoLordoProvvisiorioExpected.compareTo(rendimentoLordoProvvisiorioDB) == 0); 

это терпеть неудачу, потому что rendimentoLordoProvvisiorioExpected, кажется 2.850000000000000088817841970012523233890533447265625 и не 2,85000 (как выставиться).

Почему? Как я могу изменить предыдущий код, чтобы установить rendimentoLordoProvvisiorio Ожидаемый к ожидаемому значению 2.85000?

+3

Вы инициализируете 'rendimentoLordoProvvisiorioExpected', используя двойной, который не является точным. Попробуйте инициализировать его с помощью String. – hotzst

+1

Интересно, почему вы даже не прочитали, что такое JavaDoc ['BigDecimal (double)'] (https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#BigDecimal -double-). Он говорит вам, что 'double' не точный, что вы должны использовать вместо этого. – Tom

ответ

4

Поскольку вы инициализируете BigDecimal значением с плавающей запятой, вызывая конструктор с двойным. Удваивает числа с плавающей запятой. Используйте строку:

BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal("2.85000"); 

Вы должны прочитать documentation of BigDecimal regarding calling the double version of the constructor.

Когда вы используете BigDecimal, вы преобразуете базовую пару с плавающей запятой в базовое число с плавающей запятой. Там нет идеальной базы две с плавающей точкой представления числа 2,85, наилучшее приближение, как представляется, ряд близко к:

>>> decimal.Decimal(2.85) 
Decimal('2.850000000000000088817841970012523233890533447265625') 

Вы должны прочитать больше о плавающей точке, например What Every Programmer Should Know About Floating-Point Arithmetic.

6

Использовать BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal("2.85000"); вместо BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal(2.85000); Что вы сделали, так это построить BigDecimal из двойника, а двойники не точны.

+0

Что вы имеете в виду, что двойные примечания точны? Это приближение или что? – AndreaNobili

+1

@AndreaNobili Research .... http://stackoverflow.com/questions/588004/is-floating-point-math-broken – Tom

+0

Потому что вы вызываете конструктор BigDecimal с двойным. Удваивает числа с плавающей запятой. Вот почему вы должны использовать строку. – vz0

Смежные вопросы