-
Notifications
You must be signed in to change notification settings - Fork 387
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
Possible issues with the IComparable interface and associated operators #1367
Comments
My head hurts 😅 Yes there is a potential rounding error on all these:
However, I believe this only happens if the units are different. I don't immediately see how we can avoid this though. Any ideas?
Could you elaborate? Do you mean to take an average of the two results?
Rational numbers can probably help in the cases where rational numbers can be defined, but I guess it can't solve all our units? I've redirected #1368 in here too, as it seems to touch the same topic. |
The idea was that the rounding error may only occur in the one direction so that (hopefully) at least of the CompareTo operations has it right. As for the rationals - I don't see why using something like this wouldn't work (as long as we keep the fractions normalized - we could have the exact equality contract back). The only downside I see is the performance hit (and the extra dependency, should we decide the take it/expose it). |
No release date for v6 yet, some work still remains and there are already pretty big changes in there, so I plan to keep prerelease versions out for some time so we can gather a bit of feedback.
I'd be interested to test it out and get a better feel of the tradeoffs, but in essence, it would be like replacing |
I'm not sure there is a limit to the BigInterger- i think you can put as many bits as you like.. |
Ok, just a heads up- I've started work on "re-fractioning" the v6 here. I'll create a PR as soon as I figure out the |
Cool, keep me posted on how it works out 🙌 |
@angularsen
And here are the benchmark results (the conversion methods are just about 10x slower- which I think is a very small price to pay):
After:
And here is a snippet of the generated code:
I'll review my changes later (or more likely tomorrow) and open the PR. The tests still do not compile (haven't even started updating them yet) but I think we have enough to get us started on the discussion of the future role (if any) of the doubles, the QuantityType and the use of Fraction for the interfaces.. |
PS In the second benchmark I'm returning Fractions instead of doubles (As/ToProperty), so the comparison isn't exactly fair- we'd have to possibly include the cost of converting from a Fraction to double (but that's another benchmark- which we should offer to the original library, with our best regards and so on..) |
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
This issue was automatically closed due to inactivity. |
Hey guys,
I've mentioned this issue back in #838 where the current implementation of the CompareTo is prone to the same rounding issues as with the old equality contract. Here's the test that I expect would still fail in the current code base:
This might not be an issue when sorting a collection (although it might not be obvious why sorting [x1, x2, x3] might yield a different ordering as compared to the result of sorting [x2, x1, x3]), however I'm quite worried about the > operator.
Here's the typical use-case that may be problematic:
if (mass > Capacity) // possible rounding error here
I'm starting think that my proposal for handling the result of both
x1.As(x2.Unit).CompareTo(x2.Value)
andx2.As(x1.Unit).CompareTo(x1.Value)
might be "better" than what we have right now (covering 99% of the use cases) however, there is still the possibility of getting an unexpected result fromCapacity.ToUnit(x).ToUnit(y) > Capacity
..I don't know, the stricter alternative is simply too painful to imagine..
PS There is still the option of trying to use rational numbers for the underlying type: now that there is only one interface to implement this could probably be hidden from the client (say we store the fraction inside the QuantityValue). There is probably just the issue with serializing a rational using the single-value contract (some precision maybe lost), however we could roll out a RationSerializationSerializer for those that need it..
Obviously this wouldn't be as "lightweight" as what we have right now, and there is also the possible issues with the external dependency (e.g. compatibility with the older/compact frameworks etc)..
The text was updated successfully, but these errors were encountered: