unitsofmeasurement / uom-systems

Units of Measurement Systems
http://www.uom.systems
Other
36 stars 17 forks source link

Restrict formatting of nested prefixes for UCUM #108

Open keilw opened 7 years ago

keilw commented 7 years ago

Currently UCUMFormat works as designed for prefixes like MICRO:

System.out.println(FORMAT_CS.format(MICRO(LITER))); //prings OUT: uL

However when "nested" operations are applied behind such prefix, you get results like:

System.out.println(FORMAT_CS.format(MICRO(LITER).multiply(10))); //it doesn't work OUT: dauL

The UCUM spec under http://unitsofmeasure.org/ucum.html#section-Semantics §10 nested terms states

Parenthesized terms are not considered unit atoms and hence must not be preceded by a prefix.

So combining something like .multiply(10) with MICRO(LITER) whether in front or behind it seems illegitimate for UCUM.

Since it would not be nice to throw an exception in such case, a reasonable alternate representation should be found, e.g. uL*10 instead of dauL.

keilw commented 7 years ago

Also see some comments in https://github.com/unitsofmeasurement/uom-systems/issues/107

keilw commented 7 years ago

@magnonasc @garretwilson any thoughts on this?

magnonasc commented 7 years ago

Since it would not be nice to throw an exception in such case, a reasonable alternate representation should be found, e.g. uL*10 instead of dauL.

It sounds reasonable, my thought of that is that it should mix the prefix into a single one if it's within its range, and just multiply if not, or, as presented by you, if any prefix is already used like MICRO, you just use the other converters separated. So you have these two approachs to use: uL multiplied by 0,001 should be shown as nL, or, uL multiplied by 0,001 should be shown as uL.10*-3.

I don't remember if there's anything about it in specific in the docs, but if not, you should choose one, you I think you already did, and it's a good choice.

Parenthesized terms are not considered unit atoms and hence must not be preceded by a prefix.

So I think it means that [GIL_BR] multiplied by something must return the unit multiplied instead of combined with a unit like MICRO or another one.

keilw commented 7 years ago

Actually parentheses (‘(’ and ‘)’) are not the square brackets which have a different meaning, alltogether there are at least 3 types of brackets in the UCUM specification.

Whether uL multiplied by 0.001 can be shown as nL depends quite a bit on https://github.com/unitsofmeasurement/uom-se/issues/164 in an underlying implementation (uom-se and the RI should behave identical wherever possible) I found some leads already, especially converters from and to a particular unit, but still need to investigate how Unit.equals() could be improved on an implementation level similar to what's already been done with Quantity.

magnonasc commented 7 years ago

But the parenthesis in PRINT becomes square brackets in the other types, doesn't it? Or is it about other parenthesis?

keilw commented 7 years ago

No it's the round one "(" or ")" that can surround certain operations, e.g. 1 * (2+3). It's part of the BNF.