25 template <
typename T>
constexpr auto abs(
const T& a) -> T {
26 if constexpr (std::is_unsigned_v<T>) {
29 return (a < T(0)) ? -a : a;
41 template <Integral Mn>
constexpr auto gcd_recur(
const Mn& _m,
const Mn& _n) -> Mn {
62 template <Integral Mn>
constexpr auto gcd(
const Mn& _m,
const Mn& _n) -> Mn {
80 template <Integral Mn>
constexpr auto lcm(
const Mn& _m,
const Mn& _n) -> Mn {
81 if (_m == 0 || _n == 0) {
122 if (this->_den < Z(0)) {
123 this->_num = -this->
_num;
124 this->_den = -this->
_den;
134 Z common =
gcd(this->_num, this->_den);
135 if (common == Z(1) || common == Z(0)) {
138 this->_num /= common;
139 this->_den /= common;
163 [[nodiscard]]
constexpr auto num() const noexcept -> const Z& {
return _num; }
170 [[nodiscard]]
constexpr auto den() const noexcept -> const Z& {
return _den; }
182 return this->_num * rhs._den - this->_den * rhs._num;
199 if (lhs._den == Z(1) || rhs == Z(0)) {
200 return lhs._num == rhs;
202 std::swap(lhs._den, rhs);
204 return lhs._num == lhs._den * rhs;
216 if (lhs._den == Z(1) || rhs == Z(0)) {
217 return lhs._num < rhs;
219 std::swap(lhs._den, rhs._num);
221 return lhs._num < lhs._den * rhs;
233 if (rhs._den == Z(1) || lhs == Z(0)) {
234 return lhs < rhs._num;
236 std::swap(rhs._den, lhs);
238 return rhs._den * lhs < rhs._num;
270 if (lhs._den == rhs._den) {
271 return lhs._num == rhs._num;
273 std::swap(lhs._den, rhs._num);
276 return lhs._num * rhs._den == lhs._den * rhs._num;
288 if (lhs._den == rhs._den) {
289 return lhs._num < rhs._num;
291 std::swap(lhs._den, rhs._num);
294 return lhs._num * rhs._den < lhs._den * rhs._num;
340 constexpr auto operator>(
const Z& rhs)
const ->
bool {
return rhs < *
this; }
349 constexpr auto operator<=(
const Z& rhs)
const ->
bool {
return !(rhs < *
this); }
358 constexpr auto operator>=(
const Z& rhs)
const ->
bool {
return !(*
this < rhs); }
402 constexpr void reciprocal() noexcept(std::is_nothrow_swappable_v<Z>) {
403 std::swap(this->_num, this->_den);
414 std::swap(this->_num, rhs._num);
417 this->_num *= rhs._num;
418 this->_den *= rhs._den;
440 std::swap(this->_num, rhs);
475 std::swap(this->_den, rhs._num);
478 this->_num *= rhs._den;
479 this->_den *= rhs._num;
501 std::swap(this->_den, rhs);
537 res._num = -res._num;
548 if (this->_den == rhs._den) {
549 return Fraction(this->_num + rhs._num, this->_den);
551 const auto common =
gcd(this->_den, rhs._den);
552 if (common == Z(0)) {
553 return Fraction(rhs._den * this->_num + this->_den * rhs._num, Z(0));
555 const auto l = this->_den / common;
556 const auto r = rhs._den / common;
557 auto d = this->_den * r;
558 auto n = r * this->_num + l * rhs._num;
559 return Fraction(std::move(n), std::move(d));
611 if (this->_den == rhs._den) {
612 this->_num -= rhs.
_num;
618 std::swap(this->_den, other._num);
620 auto common_d = other.normalize2();
621 std::swap(this->_den, other._num);
622 this->_num = this->
cross(other);
623 this->_den *= other._den;
624 std::swap(this->_den, common_d);
626 this->_num *= common_n;
627 this->_den *= common_d;
647 if (this->_den == Z(1)) {
653 std::swap(this->_den, other);
655 std::swap(this->_den, other);
656 this->_num -= other * this->
_den;
657 this->_num *= common_n;
692 return (-frac) + Z(c);
717 os <<
"(" << frac.num() <<
"/" << frac.den() <<
")";
Common C++20 concepts: Ring, OrderedRing, Integral, Sequence.
Definition ck_concepts.hpp:11
constexpr auto lcm(const Mn &_m, const Mn &_n) -> Mn
Least common multiple.
Definition fractions.hpp:80
constexpr auto gcd_recur(const Mn &_m, const Mn &_n) -> Mn
Greatest common divider.
Definition fractions.hpp:41
constexpr auto abs(const T &a) -> T
absolute
Definition fractions.hpp:25
constexpr auto gcd(const Mn &_m, const Mn &_n) -> Mn
Greatest common divisor.
Definition fractions.hpp:62
Fraction.
Definition fractions.hpp:92
friend constexpr auto operator*(const Z &lhs, Fraction rhs) -> Fraction
multiply
Definition fractions.hpp:464
friend constexpr auto operator<(Fraction lhs, Z rhs) -> bool
Less than.
Definition fractions.hpp:215
constexpr void reciprocal() noexcept(std::is_nothrow_swappable_v< Z >)
reciprocal
Definition fractions.hpp:402
friend auto operator<<(Stream &os, const Fraction &frac) -> Stream &
Definition fractions.hpp:715
friend constexpr auto operator*(int &&c, const Fraction &frac) -> Fraction
Definition fractions.hpp:702
Z _den
Definition fractions.hpp:94
constexpr auto operator+=(const Fraction &rhs) -> Fraction &
Definition fractions.hpp:602
friend constexpr auto operator+(int &&c, const Fraction &frac) -> Fraction
Definition fractions.hpp:680
constexpr auto operator-=(const Fraction &rhs) -> Fraction &
Definition fractions.hpp:610
constexpr auto operator-(const Fraction &frac) const -> Fraction
Subtract.
Definition fractions.hpp:568
constexpr auto operator-(const Z &i) const -> Fraction
Definition fractions.hpp:594
friend constexpr auto operator-(int &&c, const Fraction &frac) -> Fraction
Definition fractions.hpp:691
constexpr Fraction()
Default construct a new Fraction object (0/1).
Definition fractions.hpp:156
constexpr Fraction(Z num, Z den)
Construct a new Fraction object from two values.
Definition fractions.hpp:102
friend constexpr auto operator/(Fraction lhs, const Fraction &rhs) -> Fraction
divide
Definition fractions.hpp:490
constexpr auto operator*=(Fraction rhs) -> Fraction &
multiply and assign
Definition fractions.hpp:413
friend constexpr auto operator>=(const Z &lhs, const Fraction &rhs) -> bool
Greater than or euqal to.
Definition fractions.hpp:392
constexpr auto operator>=(const Z &rhs) const -> bool
Greater than or equal to.
Definition fractions.hpp:358
constexpr auto normalize() -> Z
normalize to a canonical form
Definition fractions.hpp:111
constexpr auto num() const noexcept -> const Z &
Definition fractions.hpp:163
constexpr Fraction(const Z &num)
Construct a new Fraction object from a single value (const ref).
Definition fractions.hpp:151
constexpr auto cross(const Fraction &rhs) const -> Z
Cross product of two fractions.
Definition fractions.hpp:181
friend constexpr auto operator<=(const Z &lhs, const Fraction &rhs) -> bool
Less than or equal to.
Definition fractions.hpp:380
constexpr void normalize1()
normalize to a canonical form
Definition fractions.hpp:121
friend constexpr auto operator==(Fraction lhs, Z rhs) -> bool
Equal to.
Definition fractions.hpp:198
friend constexpr auto operator-(const Z &c, const Fraction &frac) -> Fraction
Definition fractions.hpp:669
friend constexpr auto operator/(Fraction lhs, const Z &rhs) -> Fraction
divide
Definition fractions.hpp:514
Z _num
Definition fractions.hpp:93
constexpr auto operator>=(const Fraction &rhs) const -> bool
Greater than or euqal to.
Definition fractions.hpp:322
friend constexpr auto operator+(const Z &i, Fraction frac) -> Fraction
Add.
Definition fractions.hpp:586
constexpr auto operator/=(Fraction rhs) -> Fraction &
divide and assign
Definition fractions.hpp:474
friend constexpr auto operator==(const Z &lhs, const Fraction &rhs) -> bool
Equal to.
Definition fractions.hpp:249
constexpr auto operator>(const Fraction &rhs) const -> bool
Greater than.
Definition fractions.hpp:313
friend constexpr auto operator*(Fraction lhs, const Z &rhs) -> Fraction
multiply
Definition fractions.hpp:453
constexpr auto operator-() const -> Fraction
Negate.
Definition fractions.hpp:535
constexpr friend auto operator==(Fraction lhs, Fraction rhs) -> bool
Equal to.
Definition fractions.hpp:269
constexpr auto operator+=(const Z &i) -> Fraction &
Definition fractions.hpp:638
constexpr auto operator*=(Z rhs) -> Fraction &
multiply and assign
Definition fractions.hpp:439
constexpr auto operator<=(const Fraction &rhs) const -> bool
Less than or equal to.
Definition fractions.hpp:331
constexpr friend auto operator<(Fraction lhs, Fraction rhs) -> bool
Less than.
Definition fractions.hpp:287
constexpr auto operator!=(const Fraction &rhs) const -> bool
Definition fractions.hpp:304
constexpr Fraction(Z &&num)
Construct a new Fraction object from a single value (rvalue).
Definition fractions.hpp:146
friend constexpr auto operator+(Fraction frac, const Z &i) -> Fraction
Add.
Definition fractions.hpp:577
constexpr auto operator-=(const Z &rhs) -> Fraction &
Definition fractions.hpp:646
constexpr auto operator<=(const Z &rhs) const -> bool
Less than or equal to.
Definition fractions.hpp:349
constexpr auto operator/=(const Z &rhs) -> Fraction &
divide and assign
Definition fractions.hpp:500
constexpr auto den() const noexcept -> const Z &
Definition fractions.hpp:170
constexpr auto normalize2() -> Z
normalize to a canonical form
Definition fractions.hpp:133
friend constexpr auto operator*(Fraction lhs, const Fraction &rhs) -> Fraction
multiply
Definition fractions.hpp:429
friend constexpr auto operator<(Z lhs, Fraction rhs) -> bool
Less than.
Definition fractions.hpp:232
constexpr auto operator>(const Z &rhs) const -> bool
Greater than.
Definition fractions.hpp:340
friend constexpr auto operator/(const Z &lhs, Fraction rhs) -> Fraction
divide
Definition fractions.hpp:525
constexpr auto operator+(const Fraction &rhs) const -> Fraction
Add.
Definition fractions.hpp:547
friend constexpr auto operator>(const Z &lhs, const Fraction &rhs) -> bool
Greater than.
Definition fractions.hpp:368