Skip to content

Commit 1b07158

Browse files
committed
fix rational number
1 parent 879824a commit 1b07158

File tree

1 file changed

+34
-13
lines changed

1 file changed

+34
-13
lines changed

rational/rational_number.hpp

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
#pragma once
2+
#include <cassert>
23
#include <limits>
34

45
// Rational number + {infinity(1 / 0), -infiity(-1 / 0), nan(0 / 0)} (有理数)
5-
// Do not compare any number with nan
66
// Verified: Yandex Cup 2022 Final E https://contest.yandex.com/contest/42710/problems/K
7-
template <class Int, bool AlwaysReduce = false> struct Rational {
8-
Int num, den;
7+
template <class Int, bool AutoReduce = false> struct Rational {
8+
Int num, den; // den >= 0
9+
910
static constexpr Int my_gcd(Int a, Int b) {
1011
// return __gcd(a, b);
1112
if (a < 0) a = -a;
1213
if (b < 0) b = -b;
1314
while (a and b) {
14-
if (a > b)
15+
if (a > b) {
1516
a %= b;
16-
else
17+
} else {
1718
b %= a;
19+
}
1820
}
1921
return a + b;
2022
}
23+
2124
constexpr Rational(Int num = 0, Int den = 1) : num(num), den(den) { normalize(); }
2225
constexpr void normalize() noexcept {
23-
if constexpr (AlwaysReduce) { // reduction
26+
if constexpr (AutoReduce) { // reduction
2427
Int g = my_gcd(num, den);
2528
if (g) num /= g, den /= g;
2629
} else {
@@ -31,12 +34,16 @@ template <class Int, bool AlwaysReduce = false> struct Rational {
3134
}
3235
if (den < 0) num = -num, den = -den; // denominator >= 0
3336
}
37+
38+
constexpr bool is_finite() const noexcept { return den != 0; }
39+
constexpr bool is_infinite_or_nan() const noexcept { return den == 0; }
40+
3441
constexpr Rational operator+(const Rational &r) const noexcept {
35-
if (!den and !r.den) return Rational(num + r.num, den);
42+
if (is_infinite_or_nan() and r.is_infinite_or_nan()) return Rational(num + r.num, 0);
3643
return Rational(num * r.den + den * r.num, den * r.den);
3744
}
3845
constexpr Rational operator-(const Rational &r) const noexcept {
39-
if (!den and !r.den) return Rational(num - r.num, den);
46+
if (is_infinite_or_nan() and r.is_infinite_or_nan()) return Rational(num - r.num, 0);
4047
return Rational(num * r.den - den * r.num, den * r.den);
4148
}
4249
constexpr Rational operator*(const Rational &r) const noexcept {
@@ -51,23 +58,36 @@ template <class Int, bool AlwaysReduce = false> struct Rational {
5158
constexpr Rational &operator/=(const Rational &r) noexcept { return *this = *this / r; }
5259
constexpr Rational operator-() const noexcept { return Rational(-num, den); }
5360
constexpr Rational abs() const noexcept { return Rational(num > 0 ? num : -num, den); }
61+
62+
constexpr Int floor() const {
63+
assert(is_finite());
64+
if (num > 0) {
65+
return num / den;
66+
} else {
67+
return -((-num + den - 1) / den);
68+
}
69+
}
70+
5471
constexpr bool operator==(const Rational &r) const noexcept {
55-
if constexpr (AlwaysReduce) {
72+
if (is_infinite_or_nan() or r.is_infinite_or_nan()) {
5673
return num == r.num and den == r.den;
5774
} else {
5875
return num * r.den == r.num * den;
5976
}
6077
}
78+
6179
constexpr bool operator!=(const Rational &r) const noexcept { return !(*this == r); }
80+
6281
constexpr bool operator<(const Rational &r) const noexcept {
63-
if (den == 0 and r.den == 0)
82+
if (is_infinite_or_nan() and r.is_infinite_or_nan())
6483
return num < r.num;
65-
else if (den == 0)
84+
else if (is_infinite_or_nan()) {
6685
return num < 0;
67-
else if (r.den == 0)
86+
} else if (r.is_infinite_or_nan()) {
6887
return r.num > 0;
69-
else
88+
} else {
7089
return num * r.den < den * r.num;
90+
}
7191
}
7292
constexpr bool operator<=(const Rational &r) const noexcept {
7393
return (*this == r) or (*this < r);
@@ -76,6 +96,7 @@ template <class Int, bool AlwaysReduce = false> struct Rational {
7696
constexpr bool operator>=(const Rational &r) const noexcept {
7797
return (r == *this) or (r < *this);
7898
}
99+
79100
constexpr explicit operator double() const noexcept { return (double)num / (double)den; }
80101
constexpr explicit operator long double() const noexcept {
81102
return (long double)num / (long double)den;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy