Skip to the content.

:warning: library/math/Fraction.hpp

Depends on

Code

#pragma once
template <std::integral T> struct Fraction {
    T num, den;
    Fraction(T n = 0, T d = 1) : num(n), den(d) {
        assert(den != 0);
        if (den < 0)
            num = -num, den = -den;
        T g = std::gcd(abs(num), abs(den));
        num /= g;
        den /= g;
    }

    Fraction operator+(const Fraction &b) const {
        return Fraction(num * b.den + den * b.num, den * b.den);
    }
    Fraction operator-(const Fraction &b) const {
        return Fraction(num * b.den - den * b.num, den * b.den);
    }
    Fraction operator*(const Fraction &b) const {
        return Fraction(num * b.num, den * b.den);
    }
    Fraction operator/(const Fraction &b) const {
        return Fraction(num * b.den, den * b.num);
    }
    Fraction &operator+=(const Fraction &b) { return *this = (*this) + b; }
    Fraction &operator-=(const Fraction &b) { return *this = (*this) - b; }
    Fraction &operator*=(const Fraction &b) { return *this = (*this) * b; }
    Fraction &operator/=(const Fraction &b) { return *this = (*this) / b; }
    Fraction operator+(const T &c) const { return (*this) + Fraction(c); }
    Fraction operator-(const T &c) const { return (*this) - Fraction(c); }
    Fraction operator*(const T &c) const { return (*this) * Fraction(c); }
    Fraction operator/(const T &c) const { return (*this) / Fraction(c); }
    friend Fraction operator+(const T &c, Fraction b) {
        return Fraction(c) + b;
    }
    friend Fraction operator-(const T &c, Fraction b) {
        return Fraction(c) - b;
    }
    friend Fraction operator*(const T &c, Fraction b) {
        return Fraction(c) * b;
    }
    friend Fraction operator/(const T &c, Fraction b) {
        return Fraction(c) / b;
    }
    Fraction &operator+=(const T &c) { return *this = (*this) + c; }
    Fraction &operator-=(const T &c) { return *this = (*this) - c; }
    Fraction &operator*=(const T &c) { return *this = (*this) * c; }
    Fraction &operator/=(const T &c) { return *this = (*this) / c; }
    Fraction &operator++() { return (*this) += 1; }
    Fraction &operator--() { return (*this) -= 1; }
    Fraction &operator++(int) { return (*this) += 1; }
    Fraction &operator--(int) { return (*this) -= 1; }
    Fraction operator+() const { return *this; }
    Fraction operator-() const { return Fraction(-num, den); }

    Fraction pow(long long k) const {
        Fraction res = 1, tmp(*this);
        while (k) {
            if (k & 1)
                res *= res;
            tmp *= tmp;
            k >>= 1;
        }
        return res;
    }
    Fraction inv() { return Fraction(den, num); }

    friend std::ostream &operator<<(std::ostream &os, const Fraction &a) {
        os << a.num << "/" << a.den;
        return os;
    }
    friend std::istream &operator>>(std::istream &is, Fraction &a) {
        is >> a.num;
        a.den = 1;
        return is;
    }

#define define_cmp(op)                                                         \
    bool operator op(const Fraction &b) const {                                \
        return num * b.den op b.num * den;                                     \
    }
    define_cmp(==) define_cmp(!=) define_cmp(<) define_cmp(>) define_cmp(<=)
        define_cmp(>=)
#undef define_cmp
};
#line 2 "library/math/Fraction.hpp"
template <std::integral T> struct Fraction {
    T num, den;
    Fraction(T n = 0, T d = 1) : num(n), den(d) {
        assert(den != 0);
        if (den < 0)
            num = -num, den = -den;
        T g = std::gcd(abs(num), abs(den));
        num /= g;
        den /= g;
    }

    Fraction operator+(const Fraction &b) const {
        return Fraction(num * b.den + den * b.num, den * b.den);
    }
    Fraction operator-(const Fraction &b) const {
        return Fraction(num * b.den - den * b.num, den * b.den);
    }
    Fraction operator*(const Fraction &b) const {
        return Fraction(num * b.num, den * b.den);
    }
    Fraction operator/(const Fraction &b) const {
        return Fraction(num * b.den, den * b.num);
    }
    Fraction &operator+=(const Fraction &b) { return *this = (*this) + b; }
    Fraction &operator-=(const Fraction &b) { return *this = (*this) - b; }
    Fraction &operator*=(const Fraction &b) { return *this = (*this) * b; }
    Fraction &operator/=(const Fraction &b) { return *this = (*this) / b; }
    Fraction operator+(const T &c) const { return (*this) + Fraction(c); }
    Fraction operator-(const T &c) const { return (*this) - Fraction(c); }
    Fraction operator*(const T &c) const { return (*this) * Fraction(c); }
    Fraction operator/(const T &c) const { return (*this) / Fraction(c); }
    friend Fraction operator+(const T &c, Fraction b) {
        return Fraction(c) + b;
    }
    friend Fraction operator-(const T &c, Fraction b) {
        return Fraction(c) - b;
    }
    friend Fraction operator*(const T &c, Fraction b) {
        return Fraction(c) * b;
    }
    friend Fraction operator/(const T &c, Fraction b) {
        return Fraction(c) / b;
    }
    Fraction &operator+=(const T &c) { return *this = (*this) + c; }
    Fraction &operator-=(const T &c) { return *this = (*this) - c; }
    Fraction &operator*=(const T &c) { return *this = (*this) * c; }
    Fraction &operator/=(const T &c) { return *this = (*this) / c; }
    Fraction &operator++() { return (*this) += 1; }
    Fraction &operator--() { return (*this) -= 1; }
    Fraction &operator++(int) { return (*this) += 1; }
    Fraction &operator--(int) { return (*this) -= 1; }
    Fraction operator+() const { return *this; }
    Fraction operator-() const { return Fraction(-num, den); }

    Fraction pow(long long k) const {
        Fraction res = 1, tmp(*this);
        while (k) {
            if (k & 1)
                res *= res;
            tmp *= tmp;
            k >>= 1;
        }
        return res;
    }
    Fraction inv() { return Fraction(den, num); }

    friend std::ostream &operator<<(std::ostream &os, const Fraction &a) {
        os << a.num << "/" << a.den;
        return os;
    }
    friend std::istream &operator>>(std::istream &is, Fraction &a) {
        is >> a.num;
        a.den = 1;
        return is;
    }

#define define_cmp(op)                                                         \
    bool operator op(const Fraction &b) const {                                \
        return num * b.den op b.num * den;                                     \
    }
    define_cmp(==) define_cmp(!=) define_cmp(<) define_cmp(>) define_cmp(<=)
        define_cmp(>=)
#undef define_cmp
};
Back to top page