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.
This commit is contained in:
Chip Hogg
2022-01-08 19:34:42 -05:00
parent 409aaf4636
commit f783d7f274
2 changed files with 22 additions and 2 deletions

View File

@@ -333,7 +333,9 @@ constexpr auto operator/(Magnitude auto l, Magnitude auto r) { return l * pow<-1
template<ratio R>
requires (R.num > 0)
constexpr Magnitude auto as_magnitude() {
return detail::prime_factorization_v<R.num> / detail::prime_factorization_v<R.den>;
return pow<R.exp>(detail::prime_factorization_v<10>)
* detail::prime_factorization_v<R.num>
/ detail::prime_factorization_v<R.den>;
}
namespace detail

View File

@@ -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<ratio{4, 17}>());
check_product_with_inverse_is_identity(pi_to_the<ratio{-22, 7}>());
}
SECTION("pow() multiplies exponent")
{
CHECK(pow<0>(base_power{2}) == base_power{2, 0});
CHECK(pow<ratio{-1, 2}>(base_power{2, 3}) == base_power{2, ratio{-3, 2}});
CHECK(pow<ratio{1, 3}>(base_power<pi_base>{ratio{3, 2}}) == base_power<pi_base>{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<ratio{5, 8}>() == magnitude<base_power{2, -3}, base_power{5}>{});
}
SECTION("Supports nonzero exp")
{
constexpr ratio r{3, 1, 2};
REQUIRE(r.exp == 2);
CHECK(as_magnitude<r>() == 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<ratio{3, 4}>()) == as_magnitude<ratio{3, 4}>());
CHECK(pow<1>(pi_to_the<ratio{-1, 2}>()) == pi_to_the<ratio{-1, 2}>());
}
SECTION("Can raise to arbitrary rational power") {
CHECK(pow<ratio{-8, 3}>(pi_to_the<ratio{-1, 2}>()) == pi_to_the<ratio{4, 3}>());
}
}
namespace detail