You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
NumberValue is hard (impossible?) to implement correctly for rational numbers because of Comparable<NumberValue>
Let me explain:
Let's suppose you are implementing your own NumberValue class for rational numbers because you want to be able to perform monetary operations without rounding. Let's assume you have an instance of ⅓ and you need to implement Comparable<NumberValue>.
The natural ordering should be:
0.33333
0.3̅
0.33334
But this is harder to implement than it sounds. javax.money.NumberValue.compareTo(NumberValue) is implemented using BigDecimal conversion which is also used by org.javamoney.moneta.spi.DefaultNumberValue. However the conversion from a rational number to a BigDecimal includes rounding and we need to settle for a number of decimal places as we do not have a terminating decimal expansion. The issue is that any number of decimal places is wrong and leads to reordering of values. Let's say we settle for 5 decimal places and convert 0.3̅ to 0.33333. The issue is that 0.33333 is less than 0.333333 but 0.3̅ is greater than 0.333333. We could in theory look at the number of decimal places in the argument and use one additional decimal place. However this would make it impossible to keep the total ordering properties when the receiver is a DefaultNumberValue and the argument is a custom rational NumberValue.
The text was updated successfully, but these errors were encountered:
@marschall Thanks for raising this problem. There were a couple of discussions around floating point arithmetics and their shortcomings in Java and general at JCrete last month. We could benefit from what @andi-huber already did in the JSR 385 RI: https://github.com/unitsofmeasurement/indriya. Who knows, there could even be improvements to OpenJDK in a future version, but in either case this is not for the MR of JSR 354, but a new release.
Another alternative if ASF committers like @atsticks, @desruisseaux or myself wanted to explore that could be Apache Commons Numbers. Not sure, if a RationalNumber is already supported there, but the team is fairly small and it could welcome additional support. JavaMoney was born after some attempts in places like Apache Commons or JodaMoney did not meet the needs of many financial applications, hence, if a more general numeric support was better suited at Apache Commons than e.g. OpenJDK, we could help them with what JSRs 354 and 385 have done.
NumberValue is hard (impossible?) to implement correctly for rational numbers because of
Comparable<NumberValue>
Let me explain:
Let's suppose you are implementing your own
NumberValue
class for rational numbers because you want to be able to perform monetary operations without rounding. Let's assume you have an instance of ⅓ and you need to implementComparable<NumberValue>
.The natural ordering should be:
0.33333
0.3̅
0.33334
But this is harder to implement than it sounds.
javax.money.NumberValue.compareTo(NumberValue)
is implemented usingBigDecimal
conversion which is also used byorg.javamoney.moneta.spi.DefaultNumberValue
. However the conversion from a rational number to aBigDecimal
includes rounding and we need to settle for a number of decimal places as we do not have a terminating decimal expansion. The issue is that any number of decimal places is wrong and leads to reordering of values. Let's say we settle for 5 decimal places and convert 0.3̅ to 0.33333. The issue is that 0.33333 is less than 0.333333 but 0.3̅ is greater than 0.333333. We could in theory look at the number of decimal places in the argument and use one additional decimal place. However this would make it impossible to keep the total ordering properties when the receiver is aDefaultNumberValue
and the argument is a custom rationalNumberValue
.The text was updated successfully, but these errors were encountered: