Into a Java application I have a unit test that contains the following situation:
BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal(2.85000);
BigDecimal rendimentoLordoProvvisiorioDB = null;
rendimentoLordoProvvisiorioDB = pucManager.getRendimentoLordoProvvisorio(date);
assertTrue(rendimentoLordoProvvisiorioExpected.compareTo(rendimentoLordoProvvisiorioDB) == 0);
the value of the rendimentoLordoProvvisiorioExpected variable is manually setted to 2.85000 and the obtained value rendimentoLordoProvvisiorioDB is 2.85000.
The problem is that when I do this comparision into the assertTrue() JUnit function
assertTrue(rendimentoLordoProvvisiorioExpected.compareTo(rendimentoLordoProvvisiorioDB) == 0);
it fail because the rendimentoLordoProvvisiorioExpected seems to be 2.850000000000000088817841970012523233890533447265625 and not 2.85000 (as setted).
Why? How can I modify the previous code to set the rendimentoLordoProvvisiorioExpected to the expected value 2.85000?
Because you are initializing the BigDecimal with a floating point value, by calling the constructor with a double. Doubles are floating point numbers. Use a String:
BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal("2.85000");
You should read the documentation of BigDecimal regarding calling the double
version of the constructor.
When you use a BigDecimal, you are converting a base two floating point to a base 10 floating point number. There is no perfect base two floating point representation of the number 2.85, the best approximation seems to be a number close to:
>>> decimal.Decimal(2.85)
Decimal('2.850000000000000088817841970012523233890533447265625')
You should read more about floating point, for example What Every Programmer Should Know About Floating-Point Arithmetic.