Frac —— 分数四则运算 ======================= .. code-block:: CPP template struct Frac { T num; T den; Frac(T num_, T den_) : num(num_), den(den_) { if (den < 0) { den = -den; num = -num; } } Frac() : Frac(0, 1) {} Frac(T num_) : Frac(num_, 1) {} explicit operator double() const { return 1. * num / den; } Frac &operator+=(const Frac &rhs) { num = num * rhs.den + rhs.num * den; den *= rhs.den; return *this; } Frac &operator-=(const Frac &rhs) { num = num * rhs.den - rhs.num * den; den *= rhs.den; return *this; } Frac &operator*=(const Frac &rhs) { num *= rhs.num; den *= rhs.den; return *this; } Frac &operator/=(const Frac &rhs) { num *= rhs.den; den *= rhs.num; if (den < 0) { num = -num; den = -den; } return *this; } friend Frac operator+(Frac lhs, const Frac &rhs) { return lhs += rhs; } friend Frac operator-(Frac lhs, const Frac &rhs) { return lhs -= rhs; } friend Frac operator*(Frac lhs, const Frac &rhs) { return lhs *= rhs; } friend Frac operator/(Frac lhs, const Frac &rhs) { return lhs /= rhs; } friend Frac operator-(const Frac &a) { return Frac(-a.num, a.den); } friend bool operator==(const Frac &lhs, const Frac &rhs) { return lhs.num * rhs.den == rhs.num * lhs.den; } friend bool operator!=(const Frac &lhs, const Frac &rhs) { return lhs.num * rhs.den != rhs.num * lhs.den; } friend bool operator<(const Frac &lhs, const Frac &rhs) { return lhs.num * rhs.den < rhs.num * lhs.den; } friend bool operator>(const Frac &lhs, const Frac &rhs) { return lhs.num * rhs.den > rhs.num * lhs.den; } friend bool operator<=(const Frac &lhs, const Frac &rhs) { return lhs.num * rhs.den <= rhs.num * lhs.den; } friend bool operator>=(const Frac &lhs, const Frac &rhs) { return lhs.num * rhs.den >= rhs.num * lhs.den; } friend std::ostream &operator<<(std::ostream &os, Frac x) { T g = std::gcd(x.num, x.den); if (x.den == g) { return os << x.num / g; } else { return os << x.num / g << "/" << x.den / g; } } };