Skip to the content.

:heavy_check_mark: math/fraction.hpp

Verified with

Code

#pragma once
#include <numeric>

template <typename T = long long>
struct Fraction {
    T x, y;
    constexpr Fraction(const T _x = 0, const T _y = 1) noexcept : x(_x), y(_y) {}
    constexpr Fraction operator+(const Fraction rhs) const noexcept {
        return Fraction(*this) += rhs;
    }
    constexpr Fraction operator-(const Fraction rhs) const noexcept {
        return Fraction(*this) -= rhs;
    }
    constexpr Fraction operator*(const Fraction rhs) const noexcept {
        return Fraction(*this) *= rhs;
    }
    constexpr Fraction operator/(const Fraction rhs) const noexcept {
        return Fraction(*this) /= rhs;
    }
    constexpr Fraction operator>>(const int rhs) const noexcept {
        return Fraction(*this) >>= rhs;
    }
    constexpr Fraction &operator+=(const Fraction rhs) noexcept {
        const T l = std::lcm(y, rhs.y);
        x *= l / y;
        x += rhs.x * (l / rhs.y);
        y = l;
        const T g = std::gcd(x, y);
        x /= g;
        y /= g;
        return *this;
    }
    constexpr Fraction &operator-=(const Fraction rhs) noexcept {
        const T l = std::lcm(y, rhs.y);
        x *= l / y;
        x -= rhs.x * (l / rhs.y);
        y = l;
        return *this;
    }
    constexpr Fraction &operator*=(const Fraction rhs) noexcept {
        x *= rhs.x;
        y *= rhs.y;
        const T g = std::gcd(x, y);
        x /= g;
        y /= g;
        return *this;
    }
    constexpr Fraction &operator/=(Fraction rhs) noexcept {
        x *= rhs.y;
        y *= rhs.x;
        const T g = std::gcd(x, y);
        x /= g;
        y /= g;
        return *this;
    }
    constexpr Fraction &operator>>=(int rhs) noexcept {
        *this /= Fraction{1 << rhs};
        return *this;
    }
    bool operator==(const Fraction rhs) const noexcept {
        return x * rhs.y == y * rhs.x;
    }
    auto operator<=>(const Fraction rhs) const noexcept {
        return x * rhs.y <=> y * rhs.x;
    }
};
#line 2 "math/fraction.hpp"
#include <numeric>

template <typename T = long long>
struct Fraction {
    T x, y;
    constexpr Fraction(const T _x = 0, const T _y = 1) noexcept : x(_x), y(_y) {}
    constexpr Fraction operator+(const Fraction rhs) const noexcept {
        return Fraction(*this) += rhs;
    }
    constexpr Fraction operator-(const Fraction rhs) const noexcept {
        return Fraction(*this) -= rhs;
    }
    constexpr Fraction operator*(const Fraction rhs) const noexcept {
        return Fraction(*this) *= rhs;
    }
    constexpr Fraction operator/(const Fraction rhs) const noexcept {
        return Fraction(*this) /= rhs;
    }
    constexpr Fraction operator>>(const int rhs) const noexcept {
        return Fraction(*this) >>= rhs;
    }
    constexpr Fraction &operator+=(const Fraction rhs) noexcept {
        const T l = std::lcm(y, rhs.y);
        x *= l / y;
        x += rhs.x * (l / rhs.y);
        y = l;
        const T g = std::gcd(x, y);
        x /= g;
        y /= g;
        return *this;
    }
    constexpr Fraction &operator-=(const Fraction rhs) noexcept {
        const T l = std::lcm(y, rhs.y);
        x *= l / y;
        x -= rhs.x * (l / rhs.y);
        y = l;
        return *this;
    }
    constexpr Fraction &operator*=(const Fraction rhs) noexcept {
        x *= rhs.x;
        y *= rhs.y;
        const T g = std::gcd(x, y);
        x /= g;
        y /= g;
        return *this;
    }
    constexpr Fraction &operator/=(Fraction rhs) noexcept {
        x *= rhs.y;
        y *= rhs.x;
        const T g = std::gcd(x, y);
        x /= g;
        y /= g;
        return *this;
    }
    constexpr Fraction &operator>>=(int rhs) noexcept {
        *this /= Fraction{1 << rhs};
        return *this;
    }
    bool operator==(const Fraction rhs) const noexcept {
        return x * rhs.y == y * rhs.x;
    }
    auto operator<=>(const Fraction rhs) const noexcept {
        return x * rhs.y <=> y * rhs.x;
    }
};
Back to top page