Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NumberValue is hard to implement for rational numbers #108

Open
marschall opened this issue Dec 28, 2018 · 1 comment
Open

NumberValue is hard to implement for rational numbers #108

marschall opened this issue Dec 28, 2018 · 1 comment
Labels
Milestone

Comments

@marschall
Copy link
Member

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.

@keilw keilw added the deferred label Dec 28, 2018
@keilw keilw added this to the .Next milestone Dec 28, 2018
@keilw
Copy link
Member

keilw commented Aug 5, 2019

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants