-
Notifications
You must be signed in to change notification settings - Fork 137
Perform unit conversion in equality, comparison and arithmetic operators for Quantity (and Ratio) #1578
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
base: master
Are you sure you want to change the base?
Conversation
|
@antvaset I merged master into this a few more times but I'm not sure what the next step is. Is there anything I should be doing to make progress with this? |
If the Quantity.equal method indicates that the units of the supplied Quantity instances are not comparable by returning null, try to convert the value of the "right" Quantity to the unit of the "left" Quantity using the UCUM service. And similarly for the Quantity.equivalent method with the difference that the Equivalent evaluator returns false if the units are not comparable. A new method Ratio.fullEquivalent accepts a State and passes it to EquivalentEvaluator.equivalent so that unit conversion can be used.
AddEvaluator and SubtractEvaluator, if necessary, use the UnitConversionHelper to convert the unit of one of their operands. This strategy requires the UcumService to be accessible in the two evaluators which in turn means that any evaluator which performs addition or subtraction now requires the State instance. A few tests which had to be skipped before this change succeed now. However, the tests QtyIvlCollapse_CollapseQuantityUnits[Not]WithinPer now have to be skipped until comparison operators for Quantity consider unit conversion.
* {Less:,LessOrEqual,Greater,GreaterOrEqual}Evaluator use the new
helper function compareQuantities to support comparison of Quantities
with different but comparable units
* CqlList uses the new comparison behavior when sorting, and therefore
needs the current State instance
* Interval.get{Start,End} for the unbounded side of an interval return
a Quantity with the correct unit (the unit of the opposite end point)
* Enable previously skipped tests
Add implementations in createUcumService and DefaultUcumService.
I think this is because Interval with Quantity end points of different units now work but are expected not work. * MultiplyEvaluator and DivideEvaluator, if necessary, use the UcumService to compute the value and unit of the operation result * The various Variance and StdDev evaluators now shared code for the variance computation. The variance computation can produce a quantity with either a squared or a non-squared unit so that the both variances and standard deviations use to correct unit. * Enable previously skipped tests which involve the above evaluators and unit conversion
fe0ed6d to
2d88889
Compare
|
Updated to apply to the Kotlin conversion of the codebase as discussed in Zulip chat. All tests that I could run locally, including many newly enabled tests, pass for me. The issues mentioned in the original pull request description have been resolved. |
The pull request mostly achieves what is claimed but has draft status for now because of the following issues:
RuntimeTest.intervalOfQuantityWithDifferentUOMfails now because the expectedInvalidIntervalexception is not thrown.I think the test is wrong because both interval endpoints have the unit "mass per volume" (although spelled scaled differently) and should be acceptable for defining an
Interval<Quantity>.In the test
CQLOperationsR4Test.test, the test casetestQuantity/testQuantity4fails.The test case asserts that
4 'g' ~ 4040 'mg'is true.I can only imagine this being true due to some precision rule, but I had the impression that for unit conversion, everything has to be converted to the "more granular" unit which would mean
4000 'mg' ~ 4040 'mg'which has to be false.There are a few TODOs, mostly related to test improvements, that I would address if this pull request is otherwise acceptable.