Skip to content

Arithmetic operations on Quantity

Martin Desruisseaux edited this page Jun 19, 2018 · 7 revisions

Arithmetic operations on Quantity

This is a request to verify that the group agrees on the following points. I suggest to verify if we have agreement in the order below (e.g. it is useless to move to item 5 if we don't agree on item 4):

1. Definition of "quantity equality"

Two quantities A and B are said equal if the have equal value as defined by <the number type>.equals(Object) and equal unit of measurement as defined by Unit.equals(Object).

In pseudo-code: A.getValue().equals(B.getValue()) and A.getUnit().equals(B.getUnit())

2. Definition of "quantity equivalence"

Proposal: Two quantities A and B are said equivalent if, after conversion to the same unit of measurement by a call to Quantity.to(Unit), their numerical values are the same (ignoring rounding errors, overflow and underflow).

In pseudo-code: A.to(commonUnit).getValue()B.to(commonUnit).getValue()

Note: A is equal to B implies that A is equivalent to B. But the converse is not necessarily true: A is equivalent to B does not imply that A is equal to B.

3. Specification requirement

The Units of Measurement API 2.0 (JSR 385) SHALL describe all Quantity arithmetic operations with enough details for ensuring that different implementations produce at least equivalent results (issue #98).

Note: whether different implementations should produce equal results is not the purpose of this page. If desired, it can be a separated discussion. For the purpose of mathematical discussion in this page, only equivalence is needed.

4. Arithmetic consistency requirement

The specification of Quantity arithmetic operations SHALL be consistent with arithmetic laws. For example Quantity.add(Quantity) shall be defined in such a way that A + B is equivalent to B + A (addition commutativity) for any quantities, even if their units of measurement are not the same (issue #99).

5. Elimination of arithmetically inconsistent rules

A.add(B) operations defined by the following rules can be shown to be in violation with arithmetic laws when A and B use different units of measurement and at least one unit is a "shifted units". The most emblematic examples are arithmetic operations on temperature measurements in Kelvin et Celsius degrees, but they are not the only examples.

  • "Convert the unit of second operand (B) in the units of the first operand (A)" — break addition commutativity and associativity.
  • "Interpret the first operand (A) as a measurement and the second operand (B) as an increment" — break addition commutativity and associativity.
  • Other rules have been explored in issue #95.

6. List of arithmetically consistent rules

I believe that the only rule compliant with arithmetic laws in current API (possible API change is a separated discussion) is:

  • "Perform calculations AS IF all values were converted to system unit before the arithmetic operation."
    • Note 1: it does not mean that the result must be in system unit; implementations are free to return whatever equivalent quantity they wish.
    • Note 2: it does not mean that implementations must convert all values to system unit. Implementations are free to use whatever strategy produce equivalent results.

Alternatives rules can be proposed. If we can not find an arithmetic law violated by the alternative proposal, the alternative will be accepted as a valid choice for consideration. But until now I'm not aware of any alternative that do not involve API change.

7. Consequences of arithmetically consistent rules

Acknowledge that the consequence of applying arithmetically consistent operations without API change is that 1°C + 2°C = 276.15°C and 2*1°C = 275.15°C. Acknowledge that there is no arithmetically consistent alternative found so far. Acknowledge that even if counter-intuitive, this is an unavoidable mathematical consequence unless we change the API.

Note: while counter-intuitive, above-cited consequences on temperature measurements are actually consistent with thermodynamic laws.

8. How to reduce surprise for the users

If the group does not want to expose users to results like "1°C + 2°C = 276.15°C", we have a limited number of options. The remaining of this page list all options proposed so far (this section will be edited if new options are proposed), excluding arithmetically inconsistent options:

  • Declare 1°C + 2°C as an invalid operation.
    • Problem 1: adding temperature measurements is a valid operation when computing an average temperature, computing interpolations or applying thermodynamic formulas.
    • Problem 2: declaring 1°C + 2°C as an invalid operation would introduce an asymmetry with subtraction, where 2°C - 1°C is a valid operation.
  • Encourage implementations to return the result of 1°C + 2°C in Kelvin instead then Celsius degrees. Users may guess more easily what is happening if they see 549.3 K instead of 276.15°C.
  • Introduce API change for allowing implementations to differentiate measurements from differences (or increments). The API change may be a new type or an enumeration value; any solution that allow Quantity.add(Quantity) to know for example that the 2°C value in "1°C + 2°C" is an increment rather than a measurement may fit. Details of such API change would be a separated discussion.
Clone this wiki locally