forked from mpusz/mp-units
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>;
|
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
|
} // 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
|
} // namespace
|
||||||
|
Reference in New Issue
Block a user