From 5afe7766e97f47ae9866e69503bfd9fe9e13a146 Mon Sep 17 00:00:00 2001 From: Chip Hogg Date: Sat, 9 Apr 2022 17:49:39 +0000 Subject: [PATCH] Use Magnitude implementation for `base_units_ratio` This resolves a TODO and lets us use arbitrary exponent denominators. I also attempt to clarify the semantics. This is based on my best effort of understanding pre-existing concepts in the library, so I hope I got it right! --- .../include/units/bits/base_units_ratio.h | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/core/include/units/bits/base_units_ratio.h b/src/core/include/units/bits/base_units_ratio.h index c29658c2..dad86a67 100644 --- a/src/core/include/units/bits/base_units_ratio.h +++ b/src/core/include/units/bits/base_units_ratio.h @@ -24,29 +24,35 @@ #include #include +#include #include namespace units::detail { -template - requires(E::den == 1 || E::den == 2) // TODO provide support for any den -constexpr ratio exp_ratio() +/** + * @brief Calculates the "absolute" magnitude of the derived dimension defined by this list. + * + * "Absolute" magnitudes are not physically observable: only ratios of magnitudes are. For example: if we multiplied + * all magnitudes in the system by the same constant, no meaningful results would change. However, in practice, we need + * to make some global choice for the "absolute" values of magnitudes, so that we can compute their ratios. + * + * The point of this function is to compute the absolute magnitude of a derived dimension, in terms of the absolute + * magnitudes of its constituent dimensions. + */ +template +constexpr Magnitude auto absolute_magnitude(exponent_list) { - const ratio base_ratio = E::dimension::base_unit::ratio; - const ratio positive_ratio = - E::num * E::den < 0 ? ratio(base_ratio.den, base_ratio.num, -base_ratio.exp) : base_ratio; - const std::intmax_t N = E::num * E::den < 0 ? -E::num : E::num; - const ratio ratio_pow = pow(positive_ratio); - return E::den == 2 ? sqrt(ratio_pow) : ratio_pow; + return (pow(Es::dimension::base_unit::mag) * ... * magnitude<>{}); } /** * @brief Calculates the common ratio of all the references of base units in the derived dimension */ template -constexpr ratio base_units_ratio(exponent_list) +constexpr ratio base_units_ratio(exponent_list es) { - return (exp_ratio() * ... * ratio(1)); + return as_ratio(absolute_magnitude(es)); } + } // namespace units::detail