Support addition and negation in ratio

This commit is contained in:
Chip Hogg
2021-12-29 07:51:16 -05:00
parent 3bf3bebb6a
commit a80378cae8
2 changed files with 28 additions and 0 deletions

View File

@@ -60,6 +60,27 @@ struct ratio {
[[nodiscard]] friend constexpr bool operator==(const ratio&, const ratio&) = default;
[[nodiscard]] friend constexpr ratio operator-(const ratio& r)
{
return ratio(-r.num, r.den, r.exp);
}
[[nodiscard]] friend constexpr ratio operator+(ratio lhs, ratio rhs)
{
// First, get the inputs into a common exponent.
const auto common_exp = std::min(lhs.exp, rhs.exp);
auto commonify = [common_exp](ratio &r) {
while (r.exp > common_exp) {
r.num *= 10;
--r.exp;
}
};
commonify(lhs);
commonify(rhs);
return ratio{lhs.num * rhs.den + lhs.den * rhs.num, lhs.den * rhs.den, common_exp};
}
[[nodiscard]] friend constexpr ratio operator*(const ratio& lhs, const ratio& rhs)
{
const std::intmax_t gcd1 = std::gcd(lhs.num, rhs.den);

View File

@@ -40,6 +40,13 @@ static_assert(ratio(4) * ratio(1, 2) == ratio(2));
static_assert(ratio(1, 8) * ratio(2) == ratio(1, 4));
static_assert(ratio(1, 2) * ratio(8) == ratio(4));
// ratio negation
static_assert(-ratio(3, 8) == ratio(-3, 8));
// ratio addition
static_assert(ratio(1, 2) + ratio(1, 3) == ratio(5, 6));
static_assert(ratio(1, 3, 2) + ratio(11, 6) == ratio(211, 6)); // 100/3 + 11/6
// multiply with exponents
static_assert(ratio(1, 8, 2) * ratio(2, 1, 4) == ratio(1, 4, 6));
static_assert(ratio(1, 2, -4) * ratio(8, 1, 3) == ratio(4, 1, -1));