JavaMoney / jsr354-ri

JSR 354 - Moneta: Reference Implementation
Other
334 stars 100 forks source link

Unexpected rounding behaviour using FastMoney #384

Closed devmop closed 7 months ago

devmop commented 1 year ago

Apologies for the long test case attached.

We've been exploring using JavaMoney for some internal currency conversions using an internal exchange rate provider. Unit testing has thrown up some undesirable interactions which I believe I've tracked down and identified workarounds but it seems worthy of a report.

The attached tests attempt to convert 100 GBP to JPY with a rate of 175 expressed as range of Number implementations. All tests except for FastMoney with Float and Double pass as expected. Reporting a total JPY of 17500. Float and Double however generate 20000 JPY which is an incredible amount of error.

The cause appears to be in org.javamoney.moneta.spi.AbstractCurrencyConversion#roundFactor When using Money no scaling is applied as the underlying value is BigDecimal and the supplied exchange rate is applied directly.

For FastMoney it takes the main branch, finds the scale and attempts to round. For all cases except floats/doubles the scale is zero by virtue of the attempts to strip trailing zeros, and the MathContext then is asked for precision 0 and applies no rounding. Double/Float however get scale 1 and the MathContext is asked for precision 1. This returns a result with a single significant figure of 200 in the case of 175 in the tests.

I believe this is also the same errors as were seen in https://github.com/JavaMoney/jsr354-ri/issues/303

FastMoneyRoundingError.txt

keilw commented 1 year ago

This was probably fixed already, but if it still happens with the 1.4.3-SNAPSHOT builds, could you please provide the text file for TestNG instead of JUnit 5? (all tests in the RI are TestNG and we can't change that with the constrained resources in maintenance mode of the JSR)