mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-07 06:04:27 +02:00
Add extract_power_of_10(Magnitude)
utility
This will help with pretty-printing magnitudes by extracting a reasonable power of 10.
This commit is contained in:
@@ -656,4 +656,26 @@ constexpr Magnitude auto as_magnitude()
|
||||
detail::prime_factorization_v<R.den>;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template<typename T, BasePower auto... BPs>
|
||||
constexpr ratio get_power(T base, magnitude<BPs...>)
|
||||
{
|
||||
return ((BPs.get_base() == base ? BPs.power : ratio{0}) + ... + ratio{0});
|
||||
}
|
||||
|
||||
constexpr std::intmax_t integer_part(ratio r) { return numerator(r) / denominator(r); }
|
||||
|
||||
constexpr std::intmax_t extract_power_of_10(Magnitude auto m)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
return integer_part((detail::abs(power_of_2) < detail::abs(power_of_5)) ? power_of_2 : power_of_5);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
} // namespace units
|
||||
|
@@ -610,4 +610,30 @@ TEST_CASE("strictly_increasing")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("extract_power_of_10")
|
||||
{
|
||||
SECTION("Picks out positive powers")
|
||||
{
|
||||
CHECK(extract_power_of_10(as_magnitude<10>()) == 1);
|
||||
CHECK(extract_power_of_10(as_magnitude<20>()) == 1);
|
||||
CHECK(extract_power_of_10(as_magnitude<40>()) == 1);
|
||||
CHECK(extract_power_of_10(as_magnitude<50>()) == 1);
|
||||
CHECK(extract_power_of_10(as_magnitude<100>()) == 2);
|
||||
}
|
||||
|
||||
SECTION("Picks out negative powers")
|
||||
{
|
||||
constexpr auto ONE = as_magnitude<1>();
|
||||
CHECK(extract_power_of_10(ONE / as_magnitude<10>()) == -1);
|
||||
CHECK(extract_power_of_10(ONE / as_magnitude<20>()) == -1);
|
||||
CHECK(extract_power_of_10(ONE / as_magnitude<40>()) == -1);
|
||||
CHECK(extract_power_of_10(ONE / as_magnitude<50>()) == -1);
|
||||
CHECK(extract_power_of_10(ONE / as_magnitude<100>()) == -2);
|
||||
}
|
||||
|
||||
SECTION("Zero if signs disagree") { CHECK(extract_power_of_10(as_magnitude<2>() / as_magnitude<5>()) == 0); }
|
||||
|
||||
SECTION("Handles rational powers") { CHECK(extract_power_of_10(sqrt(as_magnitude<1000>())) == 1); }
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
Reference in New Issue
Block a user