iliekturtles / uom

Units of measurement -- type-safe zero-cost dimensional analysis
Apache License 2.0
1.02k stars 97 forks source link

Consider supporting explicit unit values (e.g. Meter, Foot) #107

Open iliekturtles opened 6 years ago

iliekturtles commented 6 years ago

Consider supporting explicit unit values (e.g. Meter, Foot). Currently uom stores everything as Quantity with an associated type for base units. This has a number of advantages but it also limits precision of units that have a very small/large conversion factor from the base units. e.g. storing a yottameter with a base unit of meters doesn't work well. Changing base units is also awkward, see https://github.com/iliekturtles/uom/issues/97#issuecomment-403583166.

iliekturtles commented 5 years ago

This would likely be part of a uom 2.0. I've started looking into it in the dev-macros branch.

IsaacTru commented 4 years ago

I also am in the situation where I need to store a value with a small conversion factor and can't deal with the precision hit that comes from converting it to the base unit. I like the generalization of using quantities versus explicit units, as this keeps the logic unit system agnostic (up to the issues mentioned in #108). So, a potential solution that comes to mind is to include another typenum parameter for each base unit that determines the power of ten the value is multiplied by. For example, to represent a yottameter, one would have the type definition type yottameter = Quantity<ISQ<(P1, P24), (Z0, Z0), (Z0, Z0), (Z0, Z0), (Z0, Z0), (Z0, Z0), (Z0, Z0)>, SI<f64>, f64>; It makes the type signature even messier (a reason I have had a hard time adopting uom in practice) but allows for expression all sorts of fun quantities without loosing precision! What do you think?

iliekturtles commented 4 years ago

While it is messy, if it works it could be a good way to have a short-term solution until I make more progress on the dev-macros branch.

chrysn commented 4 years ago

I understand this issue to be about the numerics of largly offset values, not about actually differentiating between 1000m and 1km.

To keep issues separate and not pull in a constant offset into the type (but still have ergonomically viable code), would it be possible to use a generic fixed-point type? Yottameter(42) would then just be sugar around Meter(SomeFixedDecimal::<N24>(42)), and all the arithmetic on the numbers (and any type coercion) would be deferred to the fixed point arithmetic module.

iliekturtles commented 3 years ago

@chrysn I believe you can do that now by using bigrational as the underlying storage type. The downside of this approach is that all mathematical operations are going to be much more expensive since they'll be using bigrational instead of the much more efficient f32/f64.

iliekturtles commented 3 years ago

Note to myself to review PhantomData variance: