blob: f872f6547cbd2e68989882860db63702b4f67e06 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/camera/lib/numerics/rational.h"
#include <numeric>
namespace camera::numerics {
Rational& Rational::Reduce() {
*this = camera::numerics::Reduce(*this);
return *this;
}
Rational Reduce(const Rational& r) {
auto ret = r;
auto s = std::gcd(ret.n, ret.d);
if (s > 1) {
ret.n /= s;
ret.d /= s;
}
if (ret.d < 0) {
ret.n = -ret.n;
ret.d = -ret.d;
}
return ret;
}
Rational& Rational::operator+=(const Rational& other) {
*this = *this + other;
return *this;
}
Rational& Rational::operator-=(const Rational& other) {
*this = *this - other;
return *this;
}
Rational& Rational::operator*=(const Rational& other) {
*this = *this * other;
return *this;
}
Rational& Rational::operator/=(const Rational& other) {
*this = *this / other;
return *this;
}
Rational operator+(const Rational& r) { return r; }
Rational operator-(const Rational& r) { return Reduce({.n = -r.n, .d = r.d}); }
Rational operator+(const Rational& a, const Rational& b) {
return Reduce({.n = a.n * b.d + b.n * a.d, .d = a.d * b.d});
}
Rational operator-(const Rational& a, const Rational& b) { return Reduce(a + (-b)); }
Rational operator*(const Rational& a, const Rational& b) {
return Reduce({.n = a.n * b.n, .d = a.d * b.d});
}
Rational operator/(const Rational& a, const Rational& b) {
return Reduce({.n = a.n * b.d, .d = a.d * b.n});
}
bool operator==(const Rational& a, const Rational& b) { return Reduce(a - b).n == 0; }
bool operator!=(const Rational& a, const Rational& b) { return Reduce(a - b).n != 0; }
bool operator<(const Rational& a, const Rational& b) { return Reduce(a - b).n < 0; }
bool operator<=(const Rational& a, const Rational& b) { return Reduce(a - b).n <= 0; }
bool operator>(const Rational& a, const Rational& b) { return Reduce(a - b).n > 0; }
bool operator>=(const Rational& a, const Rational& b) { return Reduce(a - b).n >= 0; }
std::ostream& operator<<(std::ostream& os, const Rational& r) {
constexpr auto kFractionSlash = u8"\u2044";
os << r.n << reinterpret_cast<const char*>(kFractionSlash) << r.d;
return os;
}
} // namespace camera::numerics