GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 22 / 0 / 22
Functions: 100.0% 5 / 0 / 5
Branches: 62.5% 5 / 0 / 8

src/math/ds/rational/lib.hpp
Line Branch Exec Source
1 #pragma once
2
3 #include "../../../nt/gl/gcd/lib.hpp"
4 #include "../../../util/traits/others/lib.hpp"
5
6 namespace tifa_libs {
7
8 template <int_c T>
9 struct rational {
10 T num, den;
11
12 23 CEXP rational(T numerator = T(0), T denominator = T(1)) NE : num{numerator}, den{denominator} {
13
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 23 times.
23 if (assert(den != 0); num == 0) den = 1;
14 else {
15 23 const T g = (T)gcd(num, den);
16 23 if CEXP (num /= g, den /= g; std::is_signed_v<T>)
17
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if (den < 0) num = -num, den = -den;
18 }
19 23 }
20
21 CEXP rational& operator+=(T x) NE {
22 num += x * den;
23 return *this;
24 }
25 CEXP rational& operator-=(T x) NE {
26 num -= x * den;
27 return *this;
28 }
29 CEXP rational& operator*=(T x) NE {
30 const T g = (T)gcd(x, den);
31 num *= x / g, den /= g;
32 return *this;
33 }
34 CEXP rational& operator/=(T x) NE {
35 assert(x);
36 const T g = (T)gcd(x, num);
37 if CEXP (num /= g, den *= x / g; std::is_signed_v<T>)
38 if (den < 0) num = -num, den = -den;
39 return *this;
40 }
41 269 CEXP rational& operator+=(rational CR x) NE {
42 269 T g = (T)gcd(den, x.den);
43 269 num = num * (x.den / g) + x.num * (den /= g);
44 269 g = (T)gcd(num, g);
45 269 num /= g, den *= x.den / g;
46 269 return *this;
47 }
48 315 CEXP rational& operator-=(rational CR x) NE {
49 315 T g = (T)gcd(den, x.den);
50 315 num = num * (x.den / g) - x.num * (den /= g);
51 315 g = (T)gcd(num, g);
52 315 num /= g, den *= x.den / g;
53 315 return *this;
54 }
55 CEXP rational& operator*=(rational CR x) NE {
56 const T g1 = (T)gcd(num, x.den), g2 = (T)gcd(x.num, den);
57 num = num / g1 * (x.num / g2);
58 den = den / g2 * (x.den / g1);
59 return *this;
60 }
61 CEXP rational& operator/=(rational CR x) NE {
62 const T g1 = (T)gcd(num, x.num), g2 = (T)gcd(den, x.den);
63 if CEXP (num = num / g1 * (x.den / g2), den = den / g2 * (x.num / g1); std::is_signed_v<T>)
64 if (den < 0) num = -num, den = -den;
65 return *this;
66 }
67 friend CEXP rational operator+(rational x, T y) NE { return x += y; }
68 friend CEXP rational operator-(rational x, T y) NE { return x -= y; }
69 friend CEXP rational operator*(rational x, T y) NE { return x *= y; }
70 friend CEXP rational operator/(rational x, T y) NE { return x /= y; }
71 friend CEXP rational operator+(rational x, rational CR y) NE { return x += y; }
72 292 friend CEXP rational operator-(rational x, rational CR y) NE { return x -= y; }
73 friend CEXP rational operator*(rational x, rational CR y) NE { return x *= y; }
74 friend CEXP rational operator/(rational x, rational CR y) NE { return x /= y; }
75 CEXP rational operator+() CNE { return *this; }
76 CEXP rational operator-() CNE { return rational(-num, den); }
77 CEXP rational& operator++() NE {
78 num += den;
79 return *this;
80 }
81 CEXP rational& operator--() NE {
82 num -= den;
83 return *this;
84 }
85 292 friend CEXP int operator<=>(rational CR x, rational CR y) NE {
86 292 const auto _ = (x - y).num;
87
2/2
✓ Branch 0 taken 269 times.
✓ Branch 1 taken 23 times.
292 retif_((_ < 0), -1, _ > 0);
88 }
89 friend CEXP bool operator==(rational CR x, rational CR y) NE { return x.num == y.num && x.den == y.den; }
90 friend auto& operator>>(istream_c auto& is, rational& x) NE { return is >> x.num >> x.den; }
91 friend auto& operator<<(ostream_c auto& os, rational CR x) NE { return os << x.num << ' ' << x.den; }
92 template <arithm_c U>
93 CEXP U convert_to() CNE { return U(num) / U(den); }
94 };
95
96 } // namespace tifa_libs
97