mpusz / mp-units

The quantities and units library for C++
https://mpusz.github.io/mp-units/
MIT License
1.07k stars 85 forks source link

Should we add `zero_Celsius` point origin? #506

Closed mpusz closed 4 months ago

mpusz commented 11 months ago

Yesterday, I stumbled upon this article: https://randomascii.wordpress.com/2023/10/17/localization-failure-temperature-is-hard/

and prototyped the following solution for it: https://godbolt.org/z/6jo6xqeb8.

Even though the "ice point" is the correct name for the beginning of the Celsius scale, it looks a bit inconsistent and harder to use compared to Fahrenheits:

const quantity_point max = si::ice_point + 43. * deg_C;
std::cout << "max: " << max.quantity_from(si::ice_point) << " (" << max.quantity_from(usc::zero_Fahrenheit).in(deg_F) << ")\n";
const quantity_point max = usc::zero_Fahrenheit + 109. * deg_F;
std::cout << "max: " << max.quantity_from(usc::zero_Fahrenheit) << " (" << max.quantity_from(si::ice_point).in(deg_C) << ")\n";

Should we add zero_Celsius as an alias for si::ice_point as well to improve the usability? If so, should the zero_Celsius be its own strong type (derived from si::ice_point) or is it enough to just make it an object of si::ice_point type. The difference will be visible in types presented in compile-time errors.

Spammed commented 11 months ago

I would say: 'zero_Celsius' is a synonym (or alias) for 'si::ice_point' and not a (derived) kind of a 'si::ice_point'. (I have to ask: Is Kelvin a Temperature-Distance? zero_Celsius - si::ice_point == 0 K ?)

mpusz commented 11 months ago

I didn't mean it to be treated as a derived thing. Inheritance here is just an implementation detail to create a strongly typed name. We do it for other entities as well. For example:

https://github.com/mpusz/mp-units/blob/32ea1bd9b46e433457b5f9496b7c7d16c45c928e/src/systems/cgs/include/mp-units/systems/cgs/cgs.h#L33

so what I meant was something like this:

inline constexpr struct zero_Celsius : decltype(ice_point) {} zero_Celsius;

but we can also do:

inline constexpr ice_point zero_Celsius;

which will not introduce a new type, and the user will still see isq::ice_point even when zero_Celsius is used in the code.

mpusz commented 11 months ago

Is Kelvin a Temperature-Distance?

Kelvin is a unit. quantity<si::kelvin> is a differential/distance/vector type. quantity_point<si::kelvin, absolute_zero> is a point type with the internal quantity value being stored relative to the absolute_zero point.

zero_Celsius - si::ice_point == 0 K

Yes, that is true. Subtracting two points gives a quantity. As those are the same points, the distance between them is zero. The only exception when we can't subtract two points is when they are absolute_point_origins as those are unaware of the unit.

chiphogg commented 11 months ago

For posterity, here's my take on this issue (as shared in our recent WG21 meeting):

mpusz commented 4 months ago

Done some time ago