From f783d7f274bf6fcbe3978a8414423cf1cb82ee04 Mon Sep 17 00:00:00 2001 From: Chip Hogg Date: Sat, 8 Jan 2022 19:34:42 -0500 Subject: [PATCH] Handle `exp` explicitly in as_magnitude() The new test actually passed without modifying the code. However, that might be implementation-dependent (presumably based on canonicalization of the `ratio` template parameter), so I wanted a more obviously correct implementation. --- src/core/include/units/magnitude.h | 4 +++- test/unit_test/runtime/magnitude_test.cpp | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/core/include/units/magnitude.h b/src/core/include/units/magnitude.h index c4964337..bc333a43 100644 --- a/src/core/include/units/magnitude.h +++ b/src/core/include/units/magnitude.h @@ -333,7 +333,9 @@ constexpr auto operator/(Magnitude auto l, Magnitude auto r) { return l * pow<-1 template requires (R.num > 0) constexpr Magnitude auto as_magnitude() { - return detail::prime_factorization_v / detail::prime_factorization_v; + return pow(detail::prime_factorization_v<10>) + * detail::prime_factorization_v + / detail::prime_factorization_v; } namespace detail diff --git a/test/unit_test/runtime/magnitude_test.cpp b/test/unit_test/runtime/magnitude_test.cpp index b32d2928..c0c8cb2e 100644 --- a/test/unit_test/runtime/magnitude_test.cpp +++ b/test/unit_test/runtime/magnitude_test.cpp @@ -86,13 +86,20 @@ TEST_CASE("base_power") SECTION("product with inverse equals identity") { auto check_product_with_inverse_is_identity = [] (auto x) { - CHECK(x * inverse(x) == as_magnitude<1>()); + CHECK(x * pow<-1>(x) == as_magnitude<1>()); }; check_product_with_inverse_is_identity(as_magnitude<3>()); check_product_with_inverse_is_identity(as_magnitude()); check_product_with_inverse_is_identity(pi_to_the()); } + + SECTION("pow() multiplies exponent") + { + CHECK(pow<0>(base_power{2}) == base_power{2, 0}); + CHECK(pow(base_power{2, 3}) == base_power{2, ratio{-3, 2}}); + CHECK(pow(base_power{ratio{3, 2}}) == base_power{ratio{1, 2}}); + } } TEST_CASE("make_ratio performs prime factorization correctly") @@ -111,6 +118,13 @@ TEST_CASE("make_ratio performs prime factorization correctly") { CHECK(as_magnitude() == magnitude{}); } + + SECTION("Supports nonzero exp") + { + constexpr ratio r{3, 1, 2}; + REQUIRE(r.exp == 2); + CHECK(as_magnitude() == as_magnitude<300>()); + } } TEST_CASE("Equality works for magnitudes") @@ -196,6 +210,10 @@ TEST_CASE("Can raise Magnitudes to rational powers") CHECK(pow<1>(as_magnitude()) == as_magnitude()); CHECK(pow<1>(pi_to_the()) == pi_to_the()); } + + SECTION("Can raise to arbitrary rational power") { + CHECK(pow(pi_to_the()) == pi_to_the()); + } } namespace detail