diff --git a/src/core/include/units/magnitude.h b/src/core/include/units/magnitude.h index 6d4a17bd..af791693 100644 --- a/src/core/include/units/magnitude.h +++ b/src/core/include/units/magnitude.h @@ -24,11 +24,13 @@ #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -545,12 +547,15 @@ namespace detail { consteval bool less(MagnitudeSpec auto lhs, MagnitudeSpec auto rhs) { - if constexpr (is_named_magnitude && is_named_magnitude) - return type_name(lhs) < type_name(rhs); - else if constexpr (!is_named_magnitude && !is_named_magnitude) + using lhs_base_t = decltype(get_base(lhs)); + using rhs_base_t = decltype(get_base(rhs)); + + if constexpr (is_named_magnitude && is_named_magnitude) + return type_name() < type_name(); + else if constexpr (!is_named_magnitude && !is_named_magnitude) return get_base(lhs) < get_base(rhs); else - return is_named_magnitude; + return is_named_magnitude; } } // namespace detail @@ -577,11 +582,10 @@ template } else if constexpr (less(H2, H1)) { return magnitude

{} * (magnitude{} * magnitude{}); } else { - constexpr auto partial_product = magnitude{} * magnitude{}; - if constexpr (is_same_v) { + constexpr auto partial_product = magnitude{} * magnitude{}; if constexpr (get_exponent(H1) + get_exponent(H2) == 0) { - return magnitude<1>{}; + return partial_product; } else { // Make a new power_v with the common base of H1 and H2, whose power is their powers' sum. constexpr auto new_head = power_v_or_T(); @@ -682,8 +686,6 @@ template return (magnitude<>{} * ... * remove_positive_power(magnitude{})); } -} // namespace detail - // Base cases, for when either (or both) inputs are the identity. [[nodiscard]] consteval auto common_magnitude(magnitude<>, magnitude<>) { return magnitude<>{}; } [[nodiscard]] consteval auto common_magnitude(magnitude<>, Magnitude auto m) @@ -718,6 +720,8 @@ template } } +} // namespace detail + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // `mag()` implementation. @@ -795,12 +799,49 @@ template const auto power_of_2 = get_power(2, m); const auto power_of_5 = get_power(5, m); - if ((power_of_2 * power_of_5).num <= 0) { - return 0; - } + if ((power_of_2 * power_of_5).num <= 0) return 0; return integer_part((detail::abs(power_of_2) < detail::abs(power_of_5)) ? power_of_2 : power_of_5); } +inline constexpr basic_symbol_text base_multiplier("× 10", "x 10"); + +template +[[nodiscard]] consteval auto magnitude_text() +{ + constexpr auto exp10 = extract_power_of_10(M); + + constexpr Magnitude auto base = M / mag_power<10, exp10>; + constexpr Magnitude auto num = numerator(base); + constexpr Magnitude auto den = denominator(base); + // TODO address the below + static_assert(base == num / den, "Printing rational powers, or irrational bases, not yet supported"); + + constexpr auto num_value = get_value(num); + constexpr auto den_value = get_value(den); + + if constexpr (num_value == 1 && den_value == 1 && exp10 != 0) { + return base_multiplier + superscript(); + } else if constexpr (num_value != 1 || den_value != 1 || exp10 != 0) { + auto txt = basic_fixed_string("[") + regular(); + if constexpr (den_value == 1) { + if constexpr (exp10 == 0) { + return txt + basic_fixed_string("]"); + } else { + return txt + " " + base_multiplier + superscript() + basic_fixed_string("]"); + } + } else { + if constexpr (exp10 == 0) { + return txt + basic_fixed_string("/") + regular() + basic_fixed_string("]"); + } else { + return txt + basic_fixed_string("/") + regular() + " " + base_multiplier + superscript() + + basic_fixed_string("]"); + } + } + } else { + return basic_fixed_string(""); + } +} + } // namespace detail } // namespace units