13 #include <type_traits> 32 inline Rational(
long long n = 0,
long long d = 1)
36 throw std::domain_error(__func__);
48 inline auto num()
const {
return _num; }
54 inline auto den()
const {
return _den; }
60 long gcd = std::gcd(_num, _den);
68 explicit operator double()
const {
69 return static_cast<double>(_num) / static_cast<double>(_den);
79 (std::is_arithmetic_v<T> &&std::is_integral_v<T>
80 && !std::is_same_v<T, bool> && !std::is_same_v<T, char>);
85 is_int_like_v<T> || std::is_same_v<T, Rational>;
92 template<
class T, std::enable_if_t<is_rational_like_v<T>> * =
nullptr>
94 if constexpr (is_int_like_v<T>) {
97 _num = _num * r._den + r._num * _den;
109 template<
class T, std::enable_if_t<is_rational_like_v<T>> * =
nullptr>
111 if constexpr (is_int_like_v<T>) {
114 _num = _num * r._den - r._num * _den;
115 _den = _den * r._den;
126 template<
class T, std::enable_if_t<is_rational_like_v<T>> * =
nullptr>
128 if constexpr (is_int_like_v<T>) {
143 template<
class T, std::enable_if_t<is_rational_like_v<T>> * =
nullptr>
146 throw std::overflow_error(
"operator/=");
148 if constexpr (is_int_like_v<T>) {
164 template<
class X,
class Y,
class FN>
165 inline friend auto helpfn(
const X &arg1,
const Y &arg2, FN fn) {
167 if constexpr (std::is_floating_point_v<X> ||
168 std::is_floating_point_v<Y>) {
170 double rout =
static_cast<double>(arg1);
171 fn(rout, static_cast<double>(arg2));
185 template<
class X,
class Y>
187 std::enable_if_t<std::is_same_v<X, Rational> || std::is_same_v<Y, Rational>>;
193 template<
class X,
class Y, is_cand
idate_t<X, Y> * =
nullptr>
195 return helpfn(x, y, [](
auto &a,
const auto &b) { a += b; });
198 template<
class X,
class Y, is_cand
idate_t<X, Y> * =
nullptr>
200 return helpfn(x, y, [](
auto &a,
const auto &b) { a -= b; });
203 template<
class X,
class Y, is_cand
idate_t<X, Y> * =
nullptr>
205 return helpfn(x, y, [](
auto &a,
const auto &b) { a *= b; });
208 template<
class X,
class Y, is_cand
idate_t<X, Y> * =
nullptr>
210 return helpfn(x, y, [](
auto &a,
const auto &b) { a /= b; });
219 template<
typename X,
typename Y, is_cand
idate_t<X, Y> * =
nullptr>
221 if constexpr (std::is_same_v<X, Y>) {
223 return x.num() * y.den() == x.den() * y.num();
224 }
else if constexpr (std::is_same_v<Y, Rational>) {
225 return x * y.den() == y.num();
227 return x.num() == x.den() * y;
237 template<
class X,
class Y, is_cand
idate_t<X, Y> * =
nullptr>
250 if constexpr (std::is_same_v<T, int>) {
253 static_cast<long long>(std::pow(r1.
num(), n));
255 static_cast<long long>(std::pow(r1.
den(), n));
258 return std::pow(static_cast<double>(r), static_cast<double>(n));
287 return os << r.
num() <<
"/" << r.
den();
297 std::cout << r1 <<
"+" << r2 <<
"=" << rout << std::endl;
299 std::cout << r1 <<
"-" << r2 <<
"=" << rout << std::endl;
301 std::cout << r1 <<
"*" << r2 <<
"=" << rout << std::endl;
303 std::cout << r1 <<
"/" << r2 <<
"=" << rout << std::endl;
306 std::cout << r5 << std::endl;
315 std::cout << r3 << std::endl;
317 std::cout <<
"simplified:" << r3 << std::endl;
318 std::cout <<
"as double:" <<
static_cast<double>(r3) << std::endl;
328 std::cout << std::boolalpha << (r4 ==
Rational{ 1, 2 }) << std::endl;
329 std::cout << std::boolalpha << (r4 !=
Rational{ 3, 4 }) << std::endl;
330 std::cout << std::boolalpha << (r4 == 0.5) << std::endl;
338 std::cout <<
pow(r4, 3) << std::endl;
339 std::cout <<
pow(r4, 3.1) << std::endl;
348 for (
long idx = 1; idx <= 8; idx++) {
352 std::cout << sum << std::endl;
353 std::cout << static_cast<double>(sum) << std::endl;
366 std::cout << c << std::endl;
367 std::cout << c1 << std::endl;
void ex4()
ex4 Potenzierung mit ganzer und mit einer reellen Zahl
auto num() const
num lese ...
friend bool operator==(const X &x, const Y &y)
operator == Vergleichsoperator
friend Rational operator-(const Rational &r)
negate eine rationale Zahl wird negiert
friend std::ostream & operator<<(std::ostream &os, const Rational &r)
operator << Ausgabe einer rationalen Zahl
void ex1()
ex1 algebraische Operationen mit rationalen Zahlen
auto den() const
den lese...
friend Rational inverse(const Rational &r)
invert inverse rationale Zahl
friend auto operator/(const X &x, const Y &y)
Rational & operator+=(const T &r)
operator +=
Rational & operator/=(const T &r)
operator /=
void ex3()
ex3 Anwendung der Vergleichsoperatoren
Rational Klasse für rationale Zahlen.
friend auto pow(const Rational &r, T n)
pow potenziere rationale Zahl
std::enable_if_t< std::is_same_v< X, Rational >||std::is_same_v< Y, Rational > > is_candidate_t
Rational(long long n=0, long long d=1)
Rational Konstruktor.
friend auto operator+(const X &x, const Y &y)
void simplify()
simplify vereinfache Bruch
void ex2()
ex2 Initialisierung,Vereinfachung, Umwandlung in eine reelle Zahl
void ex6()
ex6 Summe rationale Zahl mit reeller Zahl Summe ganze Zahl mit rationaler Zahl
friend auto operator*(const X &x, const Y &y)
static constexpr bool is_int_like_v
Rational & operator-=(const T &r)
operator -=
friend auto operator-(const X &x, const Y &y)
void ex5()
ex5 Summe aus rationalen Zahlen
friend auto helpfn(const X &arg1, const Y &arg2, FN fn)
helpfn Hilfsfunktion zur Implementierung von +,-,*,/
friend bool operator!=(const X &r1, const Y &r2)
operator != Vergleichsoperator
Rational & operator*=(const T &r)
operator *=
static constexpr bool is_rational_like_v