Arkulib
Rational.hpp
Go to the documentation of this file.
1
10#pragma once
11
12#include <cassert>
13#include <cmath>
14#include <fstream>
15#include <iostream>
16#include <numeric>
17
19#include "Tools/Utils.hpp"
20
21namespace Arkulib {
26 template<typename IntType = int>
27 class Rational {
28
29 public:
30
31 /************************************************************************************************************
32 ****************************************** CONSTRUCTOR / DESTRUCTOR ****************************************
33 ************************************************************************************************************/
34
38 inline constexpr Rational() : m_numerator(0), m_denominator(1) { verifyTemplateType(); }
39
47 constexpr Rational(
48 IntType numerator,
49 IntType denominator,
50 bool willBeReduce = true,
51 bool willDenominatorBeVerified = true
52 );
53
59 template<typename FloatingType>
60 constexpr explicit Rational(const FloatingType &nonRational);
61
66 inline constexpr Rational(const Rational<IntType> &reference) = default;
67
73 template<typename AnotherIntType>
74 constexpr explicit Rational(Rational<AnotherIntType> &copiedRational);
75
79 inline ~Rational() = default;
80
81 /************************************************************************************************************
82 ************************************************ GETTERS ***************************************************
83 ************************************************************************************************************/
84
85 [[nodiscard]] constexpr inline IntType getNumerator() const noexcept { return m_numerator; }
86
87 [[nodiscard]] constexpr inline IntType getDenominator() const noexcept { return m_denominator; }
88
94 inline const IntType &operator[](const size_t &id) const;
95
99 [[maybe_unused]] [[nodiscard]] constexpr inline IntType getLargerOperand() const noexcept {
100 return std::max(getNumerator(), getDenominator());
101 }
102
106 [[maybe_unused]] [[nodiscard]] constexpr inline IntType getLowerOperand() const noexcept {
107 return std::min(getNumerator(), getDenominator());
108 }
109
110 /************************************************************************************************************
111 ************************************************ SETTERS ***************************************************
112 ************************************************************************************************************/
113
114 constexpr inline void setNumerator(IntType numerator) { m_numerator = numerator; };
115
116 constexpr inline void setDenominator(IntType denominator) {
117 verifyDenominator(denominator);
118 m_denominator = denominator;
119 };
120
125 inline IntType &operator[](const size_t &id);
126
127 /************************************************************************************************************
128 ************************************************* STATUS ***************************************************
129 ************************************************************************************************************/
130
134 [[maybe_unused]] [[nodiscard]] inline bool isNegative() const noexcept { return getNumerator() < 0; };
135
139 [[maybe_unused]] [[nodiscard]] inline bool isInteger() const noexcept { return getDenominator() == 1; };
140
144 [[maybe_unused]] [[nodiscard]] inline bool isZero() const noexcept { return getNumerator() == 0; };
145
146 /************************************************************************************************************
147 *********************************************** OPERATOR + *************************************************
148 ************************************************************************************************************/
149
155 constexpr Rational<IntType> operator+(const Rational<IntType> &anotherRational) const;
156
163 template<typename NonRationalType>
164 constexpr inline Rational<IntType> operator+(const NonRationalType &nonRational) const {
165 return Rational<IntType>(nonRational) + *this;
166 }
167
175 template<typename NonRationalType>
176 constexpr inline friend Rational<IntType> operator+(
177 const NonRationalType nonRational,
178 const Rational<IntType> &rational
179 ) {
180 return Rational<IntType>(nonRational) + rational;
181 }
182
183 /************************************************************************************************************
184 *********************************************** OPERATOR - *************************************************
185 ************************************************************************************************************/
186
192 constexpr Rational<IntType> operator-(const Rational<IntType> &anotherRational) const;
193
200 template<typename NonRationalType>
201 constexpr inline Rational<IntType> operator-(const NonRationalType &nonRational) const {
202 return *this - Rational<IntType>(nonRational);
203 }
204
212 template<typename NonRationalType>
213 constexpr inline friend Rational<IntType> operator-(
214 const NonRationalType nonRational,
215 const Rational<IntType> &rational
216 ) {
217 return Rational<IntType>(nonRational) - rational;
218 }
219
225 constexpr inline friend Rational operator-(const Rational &rational) {
226 return Rational<IntType>(-rational.getNumerator(), rational.getDenominator());
227 }
228
229 /************************************************************************************************************
230 *********************************************** OPERATOR * *************************************************
231 ************************************************************************************************************/
232
238 constexpr Rational<IntType> operator*(const Rational<IntType> &anotherRational) const;
239
246 template<typename NonRationalType>
247 constexpr inline Rational<IntType> operator*(const NonRationalType &nonRational) const {
248 return *this * Rational<IntType>(nonRational);
249 }
250
258 template<typename NonRationalType>
259 constexpr inline friend Rational<IntType> operator*(
260 const NonRationalType nonRational,
261 const Rational<IntType> &rational
262 ) {
263 return Rational<IntType>(nonRational) * rational;
264 }
265
266 /************************************************************************************************************
267 *********************************************** OPERATOR / *************************************************
268 ************************************************************************************************************/
269
275 constexpr Rational<IntType> operator/(const Rational<IntType> &anotherRational) const;
276
283 template<typename NonRationalType>
284 constexpr inline Rational<IntType> operator/(const NonRationalType &nonRational) const {
285 return *this / Rational<IntType>(nonRational);
286 }
287
295 template<typename NonRationalType>
296 constexpr inline friend Rational<IntType> operator/(
297 const NonRationalType nonRational,
298 const Rational<IntType> &rational
299 ) {
300 return Rational<IntType>(nonRational) / rational;
301 }
302
303 /************************************************************************************************************
304 ********************************************** OPERATOR == *************************************************
305 ************************************************************************************************************/
306
312 constexpr inline bool operator==(const Rational<IntType> &anotherRational) const {
313 Rational<IntType> leftRational = simplify();
314 Rational<IntType> rightRational = anotherRational.simplify();
315
316 return (leftRational.getNumerator() == rightRational.getNumerator() &&
317 leftRational.getDenominator() == rightRational.getDenominator());
318 }
319
326 template<typename NonRationalType>
327 constexpr inline bool operator==(const NonRationalType &nonRational) const {
328 return Rational<IntType>(nonRational) == *this;
329 }
330
338 template<typename NonRationalType>
339 constexpr inline friend bool operator==(
340 const NonRationalType nonRational,
341 const Rational<IntType> &rational
342 ) {
343 return Rational<IntType>(nonRational) == rational;
344 }
345
346 /************************************************************************************************************
347 ********************************************** OPERATOR != *************************************************
348 ************************************************************************************************************/
349
355 constexpr inline bool operator!=(const Rational<IntType> &anotherRational) const {
356 Rational<IntType> leftRational = simplify();
357 Rational<IntType> rightRational = anotherRational.simplify();
358
359 return (leftRational.getNumerator() != rightRational.getNumerator() ||
360 leftRational.getDenominator() != rightRational.getDenominator());
361 }
362
369 template<typename NonRationalType>
370 constexpr inline bool operator!=(const NonRationalType &nonRational) const {
371 return Rational<IntType>(nonRational) != *this;
372 }
373
381 template<typename NonRationalType>
382 constexpr inline friend bool operator!=(
383 const NonRationalType nonRational,
384 const Rational<IntType> &rational
385 ) {
386 return Rational<IntType>(nonRational) != rational;
387 }
388
389 /************************************************************************************************************
390 *********************************************** OPERATOR < *************************************************
391 ************************************************************************************************************/
392
398 constexpr inline bool operator<(const Rational<IntType> &anotherRational) const {
399 return toRealNumber() < anotherRational.toRealNumber();
400 }
401
408 template<typename NonRationalType>
409 constexpr inline bool operator<(const NonRationalType &nonRational) const { return *this < Rational<IntType>(nonRational); }
410
418 template<typename NonRationalType>
419 constexpr inline friend bool operator<(
420 const NonRationalType nonRational,
421 const Rational<IntType> &rational
422 ) {
423 return Rational<IntType>(nonRational) < rational;
424 }
425
426 /************************************************************************************************************
427 *********************************************** OPERATOR <= *************************************************
428 ************************************************************************************************************/
429
435 constexpr inline bool operator<=(const Rational<IntType> &anotherRational) const {
436 return toRealNumber() <= anotherRational.toRealNumber();
437 }
438
445 template<typename NonRationalType>
446 constexpr inline bool operator<=(const NonRationalType &nonRational) const {
447 return *this <= Rational<IntType>(nonRational);
448 }
449
457 template<typename NonRationalType>
458 constexpr inline friend bool operator<=(
459 const NonRationalType nonRational,
460 const Rational<IntType> &rational
461 ) {
462 return Rational<IntType>(nonRational) <= rational;
463 }
464
465 /************************************************************************************************************
466 *********************************************** OPERATOR > *************************************************
467 ************************************************************************************************************/
468
474 constexpr inline bool operator>(const Rational<IntType> &anotherRational) const {
475 return toRealNumber() > anotherRational.toRealNumber();
476 }
477
484 template<typename NonRationalType>
485 constexpr inline bool operator>(const NonRationalType &nonRational) const {
486 return *this > Rational<IntType>(nonRational);
487 }
488
496 template<typename NonRationalType>
497 constexpr inline friend bool operator>(
498 const NonRationalType nonRational,
499 const Rational<IntType> &rational
500 ) {
501 return Rational<IntType>(nonRational) > rational;
502 }
503
504 /************************************************************************************************************
505 *********************************************** OPERATOR >= *************************************************
506 ************************************************************************************************************/
507
513 constexpr inline bool operator>=(const Rational<IntType> &anotherRational) const {
514 return toRealNumber() >= anotherRational.toRealNumber();
515 }
516
523 template<typename NonRationalType>
524 constexpr inline bool operator>=(const NonRationalType &nonRational) const {
525 return *this >= Rational<IntType>(nonRational);
526 }
527
535 template<typename NonRationalType>
536 constexpr inline friend bool operator>=(
537 const NonRationalType nonRational,
538 const Rational<IntType> &rational
539 ) {
540 return Rational<IntType>(nonRational) >= rational;
541 }
542
543 /************************************************************************************************************
544 *********************************************** OPERATOR += ************************************************
545 ************************************************************************************************************/
546
552 constexpr Rational<IntType> operator+=(const Rational<IntType> &anotherRational) {
553 *this = *this + anotherRational;
554 return *this;
555 }
556
563 template<typename NonRationalType>
564 constexpr inline Rational<IntType> operator+=(const NonRationalType &nonRational) {
565 *this = *this + Rational<IntType>(nonRational);
566 return *this;
567 }
568
569 /************************************************************************************************************
570 *********************************************** OPERATOR ++ ************************************************
571 ************************************************************************************************************/
572
576 constexpr inline void operator++() { *this += 1; }
577
578 /************************************************************************************************************
579 *********************************************** OPERATOR -= ************************************************
580 ************************************************************************************************************/
581
587 constexpr Rational<IntType> operator-=(const Rational<IntType> &anotherRational) {
588 *this = *this - anotherRational;
589 return *this;
590 }
591
598 template<typename NonRationalType>
599 constexpr inline Rational<IntType> operator-=(const NonRationalType &nonRational) {
600 *this = *this - Rational<IntType>(nonRational);
601 return *this;
602 }
603
604 /************************************************************************************************************
605 *********************************************** OPERATOR -- ************************************************
606 ************************************************************************************************************/
607
611 constexpr inline void operator--() { *this -= 1; }
612
613 /************************************************************************************************************
614 *********************************************** OPERATOR *= ************************************************
615 ************************************************************************************************************/
616
622 constexpr inline Rational<IntType> operator*=(const Rational<IntType> &anotherRational) {
623 *this = *this * anotherRational;
624 return *this;
625 }
626
633 template<typename NonRationalType>
634 constexpr inline Rational<IntType> operator*=(const NonRationalType &nonRational) {
635 *this = *this * Rational<IntType>(nonRational);
636 return *this;
637 }
638
639 /************************************************************************************************************
640 *********************************************** OPERATOR /= ************************************************
641 ************************************************************************************************************/
642
648 constexpr inline Rational<IntType> operator/=(const Rational<IntType> &anotherRational) {
649 *this = *this / anotherRational;
650 return *this;
651 }
652
659 template<typename NonRationalType>
660 constexpr inline Rational<IntType> operator/=(const NonRationalType &nonRational) {
661 *this = *this / Rational<IntType>(nonRational);
662 return *this;
663 }
664
665
666 /************************************************************************************************************
667 ************************************************* MATHS ****************************************************
668 ************************************************************************************************************/
669
674 [[maybe_unused]] [[nodiscard]] constexpr inline Rational<IntType> inverse() const {
676 }
677
682 [[maybe_unused]] [[nodiscard]] constexpr Rational<IntType> sqrt() const;
683
688 [[maybe_unused]] [[nodiscard]] constexpr Rational<IntType> cos() const;
689
694 [[maybe_unused]] [[nodiscard]] constexpr Rational<IntType> exp() const;
695
701 template<typename FloatingType>
702 [[maybe_unused]] [[nodiscard]] constexpr Rational<IntType> pow(const FloatingType &k) const;
703
708 [[maybe_unused]] [[nodiscard]] constexpr inline Rational<IntType> abs() const {
709 return Rational<IntType>(std::abs(getNumerator()), std::abs(getDenominator()));
710 };
711
715 [[maybe_unused]] [[nodiscard]] constexpr Rational<IntType> simplify() const noexcept;
716
717 /************************************************************************************************************
718 ************************************************* MINIMUM **************************************************
719 ************************************************************************************************************/
720
727 [[maybe_unused]] [[nodiscard]] constexpr static Rational<IntType> min(
728 Rational<IntType> rational1,
729 Rational<IntType> rational2
730 ) noexcept;
731
739 template<typename ...Args>
740 [[maybe_unused]] [[nodiscard]] constexpr static Rational<IntType> min(
741 Rational<IntType> rational,
742 Args... args
743 ) noexcept;
744
745 /************************************************************************************************************
746 ************************************************* MAXIMUM **************************************************
747 ************************************************************************************************************/
748
755 [[maybe_unused]] [[nodiscard]] constexpr static Rational<IntType> max(
756 Rational<IntType> rational1,
757 Rational<IntType> rational2
758 ) noexcept;
759
767 template<typename ...Args>
768 [[maybe_unused]] [[nodiscard]] constexpr static Rational<IntType> max(
769 Rational<IntType> rational,
770 Args... args
771 ) noexcept;
772
773 /************************************************************************************************************
774 ************************************************* STATIC ***************************************************
775 ************************************************************************************************************/
776
781 inline constexpr static Rational<IntType> Zero() noexcept { return Rational<IntType>(0, 1); }
782
787 inline constexpr static Rational<IntType> One() noexcept { return Rational<IntType>(1, 1); }
788
793 inline constexpr static Rational<IntType> Pi() noexcept { return Rational<IntType>(355, 113, false); }
794
799 [[maybe_unused]] inline constexpr static Rational<IntType> Infinite() noexcept { return Rational<IntType>(1, 0, false, false); }
800
801 /************************************************************************************************************
802 *********************************************** CONVERSION *************************************************
803 ************************************************************************************************************/
804
810 [[nodiscard]] inline constexpr Rational<IntType> toApproximation(
811 unsigned int digitsKept = Constant::DEFAULT_KEPT_DIGITS_APPROXIMATE
812 ) const;
813
818 [[nodiscard]] inline constexpr IntType toInteger() const noexcept {
819 assert(getDenominator() != 0 && "This denominator shouldn't never be equal to 0");
820 return IntType(getNumerator() / getDenominator());
821 }
822
828 template<typename FloatingType = float>
829 [[nodiscard]] inline constexpr FloatingType toRealNumber() const noexcept {
830 assert(getDenominator() != 0 && "This denominator shouldn't never be equal to 0");
831 return getNumerator() / FloatingType(getDenominator());
832 }
833
838 [[nodiscard]] inline std::string toString() const noexcept {
839 return "(" + std::to_string(getNumerator()) + " / " + std::to_string(getDenominator()) + ")";
840 }
841
849 template<typename FloatingType = double>
850 [[nodiscard]] static constexpr Rational<IntType> fromFloatingPoint(
851 FloatingType floatingRatio,
853 );
854
860 [[maybe_unused]] inline constexpr void static print(const Rational<IntType> rational) noexcept {
861 std::cout << rational.toString() << std::endl << std::endl;
862 }
863
871 template<typename... Args>
872 [[maybe_unused]] inline constexpr void static print(const Rational<IntType> rational, Args... args) noexcept {
873 std::cout << rational.toString() << std::endl;
874 print(args...);
875 }
876
877
878 protected:
879 /************************************************************************************************************
880 ********************************************* MEMBERS ******************************************************
881 ************************************************************************************************************/
882
883 IntType m_numerator;
887 /************************************************************************************************************
888 ********************************************* METHODS ******************************************************
889 ************************************************************************************************************/
890
894 constexpr inline void verifyTemplateType() const {
895 if (!std::is_integral<IntType>()) throw Exceptions::FloatTypeGivenException();
896 };
897
903 constexpr void verifyDenominator(IntType denominator, bool checkIfDenominatorIsNull = true);
904
910 template<typename AnotherIntType>
911 constexpr void verifyNumberLargeness(Rational<AnotherIntType> &anotherRational) const;
912
920 const long long int numerator,
921 const long long int denominator
922 ) {
923 Rational<long long int> errorChecker(numerator, denominator);
924 return Rational<IntType>(errorChecker);
925 // During the copy constructor, the method verifyLargeness will be executed.
926 }
927 };
928
929
930
931
932 /************************************************************************************************************
933 ************************************************************************************************************/
934
935
936
937 /************************************************************************************************************
938 ********************************************* CONSTRUCTOR DEF **********************************************
939 ************************************************************************************************************/
940
941 template<typename IntType>
943 const IntType numerator,
944 const IntType denominator,
945 const bool willBeReduce,
946 const bool willDenominatorBeVerified
947 ) : m_numerator(numerator), m_denominator(denominator) {
949 verifyDenominator(denominator, willDenominatorBeVerified);
950
951 if (willBeReduce) *this = simplify();
952 }
953
954 /************************************************************************************************************/
955
956 template<typename IntType>
957 template<typename FloatingType>
958 constexpr Rational<IntType>::Rational(const FloatingType &nonRational) {
959 verifyTemplateType();
960
961 if (std::is_integral<FloatingType>()) {
962 *this = Rational<IntType>(nonRational, 1);
963 }
964
965 else {
967
968 if (tmpRational.isZero() && Tools::roundToWantedPrecision(nonRational) != static_cast<FloatingType>(0)) {
969 // Because Very large number return 0
971 }
972
973 *this = Rational<IntType>(tmpRational);
974 }
975 }
976
977 /************************************************************************************************************/
978
979 template<typename IntType>
980 template<typename AnotherIntType>
982 : m_numerator(copiedRational.getNumerator()), m_denominator(copiedRational.getDenominator()){
983 verifyNumberLargeness(copiedRational);
984 }
985
986 /************************************************************************************************************
987 ********************************************* OPERATORS[] DEF **********************************************
988 ************************************************************************************************************/
989
990 template<typename IntType>
991 const IntType &Rational<IntType>::operator[](const size_t &id) const {
992 if (id == 0) return getNumerator();
993 else if (id == 1) return getDenominator();
995 }
996
997 template<typename IntType>
998 IntType &Rational<IntType>::operator[](const size_t &id) {
999 if (id == 0) return m_numerator;
1000 else if (id == 1) return m_denominator;
1002 }
1003
1004 /************************************************************************************************************
1005 ********************************************* OPERATOR + DEF ***********************************************
1006 ************************************************************************************************************/
1007
1008 template<typename IntType>
1009 constexpr Rational<IntType> Rational<IntType>::operator+(const Rational<IntType> &anotherRational) const {
1011 static_cast<long long int>(getNumerator()) * anotherRational.getDenominator() + getDenominator() * anotherRational.getNumerator(),
1012 static_cast<long long int>(getDenominator()) * anotherRational.getDenominator()
1013 );
1014 }
1015
1016 /************************************************************************************************************
1017 ********************************************* OPERATOR - DEF ***********************************************
1018 ************************************************************************************************************/
1019
1020 template<typename IntType>
1021 constexpr Rational<IntType> Rational<IntType>::operator-(const Rational<IntType> &anotherRational) const {
1023 static_cast<long long int>(getNumerator()) * anotherRational.getDenominator() - getDenominator() * anotherRational.getNumerator(),
1024 static_cast<long long int>(getDenominator()) * anotherRational.getDenominator()
1025 );
1026 }
1027
1028 /************************************************************************************************************
1029 ********************************************* OPERATOR * DEF ***********************************************
1030 ************************************************************************************************************/
1031
1032 template<typename IntType>
1033 constexpr Rational<IntType> Rational<IntType>::operator*(const Rational<IntType> &anotherRational) const {
1035 static_cast<long long int>(getNumerator()) * anotherRational.getNumerator(),
1036 static_cast<long long int>(getDenominator()) * anotherRational.getDenominator()
1037 );
1038 }
1039
1040 /************************************************************************************************************
1041 ********************************************* OPERATOR / DEF ***********************************************
1042 ************************************************************************************************************/
1043
1044 template<typename IntType>
1045 constexpr Rational<IntType> Rational<IntType>::operator/(const Rational<IntType> &anotherRational) const {
1047 static_cast<long long int>(getNumerator()) * anotherRational.getDenominator(),
1048 static_cast<long long int>(getDenominator()) * anotherRational.getNumerator()
1049 );
1050 }
1051
1052 /************************************************************************************************************
1053 ************************************************ MATHS DEF *************************************************
1054 ************************************************************************************************************/
1055
1056 template<typename IntType>
1058 if (isNegative()) throw Exceptions::NegativeSqrtException();
1059 return Rational<IntType>(
1060 std::sqrt(static_cast<double>(getNumerator()) / getDenominator())
1061 );
1062 }
1063
1064 template<typename IntType>
1066 return Rational<IntType>(
1067 std::cos(static_cast<double>(getNumerator()) / getDenominator())
1068 );
1069 }
1070
1071 template<typename IntType>
1073 return Rational<IntType>(
1074 std::exp(static_cast<double>(getNumerator()) / getDenominator())
1075 );
1076 }
1077
1078 template<typename IntType>
1079 template<typename FloatingType>
1080 constexpr Rational<IntType> Rational<IntType>::pow(const FloatingType &k) const {
1081 return Rational<IntType>(
1082 std::pow(static_cast<double>(getNumerator()) / getDenominator(), k)
1083 );
1084 }
1085
1086 template<typename IntType>
1088 const int gcd = std::gcd(getNumerator(), getDenominator());
1089 assert(gcd != 0 && "GCD shouldn't be equal to 0");
1090
1091 return Rational<IntType>(
1092 getNumerator() / gcd,
1093 getDenominator() / gcd,
1094 false
1095 );
1096 }
1097
1098 /************************************************************************************************************
1099 ************************************************ MINIMUM DEF ***********************************************
1100 ************************************************************************************************************/
1101
1102 template<typename IntType>
1104 const Rational<IntType> rational1,
1105 const Rational<IntType> rational2
1106 ) noexcept {
1107 return rational1 < rational2 ? rational1 : rational2;
1108 }
1109
1110 template<typename IntType>
1111 template<typename... Args>
1113 const Rational<IntType> rational,
1114 Args... args
1115 ) noexcept {
1116 return min(rational, min(args...));
1117 }
1118
1119 /************************************************************************************************************
1120 ************************************************ MAXIMUM DEF ***********************************************
1121 ************************************************************************************************************/
1122
1123 template<typename IntType>
1125 const Rational<IntType> rational1,
1126 const Rational<IntType> rational2
1127 ) noexcept {
1128 return rational1 < rational2 ? rational2 : rational1;
1129 }
1130
1131 template<typename IntType>
1132 template<typename... Args>
1134 const Rational<IntType> rational,
1135 Args... args
1136 ) noexcept {
1137 return max(rational, max(args...));
1138 }
1139
1140 /************************************************************************************************************
1141 ********************************************** CONVERSION DEF **********************************************
1142 ************************************************************************************************************/
1143
1144 template<typename IntType>
1145 constexpr Rational<IntType> Rational<IntType>::toApproximation(const unsigned int digitsKept) const {
1147 return Rational<IntType>(Tools::roundToWantedPrecision(toRealNumber<double>(), std::pow(10,digitsKept)));
1148 }
1149
1150 template<typename IntType>
1151 template<typename FloatingType>
1153 const FloatingType floatingRatio,
1154 size_t iter
1155 ) {
1156 constexpr FloatingType ZERO = 0;
1157 constexpr FloatingType ONE = 1;
1158
1159 if (floatingRatio < ZERO) {
1160 return -fromFloatingPoint(-floatingRatio, iter);
1161 }
1162
1163 if (floatingRatio <= static_cast<FloatingType>(Constant::DEFAULT_THRESHOLD_FROM_FP) || iter == 0) {
1164 return Rational<IntType>::Zero();
1165 }
1166
1167 if (floatingRatio < ONE) {
1168 assert(floatingRatio != 0 && "floatingRatio shouldn't never be equal to 0 here");
1169 return fromFloatingPoint(ONE / floatingRatio, iter).inverse();
1170 }
1171
1172 auto integerPart = static_cast<IntType>(floatingRatio);
1173 return fromFloatingPoint(floatingRatio - integerPart, iter - 1)
1174 + Rational<IntType>(integerPart, ONE);
1175 }
1176
1177 /************************************************************************************************************
1178 ************************************************ METHODS DEF ***********************************************
1179 ************************************************************************************************************/
1180
1181 template<typename IntType>
1182 template<typename AnotherIntType>
1184 Rational<AnotherIntType> &anotherRational
1185 ) const {
1186 // If the value of the other rational is above the limits of IntType
1187 if ((std::numeric_limits<IntType>::max() < anotherRational.getLargerOperand() ||
1188 std::numeric_limits<IntType>::lowest() > anotherRational.getLowerOperand())) {
1190 }
1191 // We assume (sadly) that the user won't go beyond long long int max (so naive)
1192 }
1193
1194 template<typename IntType>
1196 const IntType denominator,
1197 const bool checkIfDenominatorIsNull
1198 ) {
1199 constexpr IntType ZERO = 0;
1200 if (denominator == ZERO && checkIfDenominatorIsNull)
1202
1203 if (denominator < ZERO) {
1204 m_numerator = -m_numerator;
1205 m_denominator = -denominator;
1206 }
1207 }
1208
1209 /************************************************************************************************************
1210 ******************************************* STD::COUT OVERRIDE *********************************************
1211 ************************************************************************************************************/
1212
1220 template<typename IntType>
1221 std::ostream &operator<<(std::ostream &stream, const Rational<IntType> &rational) {
1222 return stream << rational.toString();
1223 }
1224}
1225
An exception to handle too large precision.
An exception to handle divide by 0.
An exception to handle Rational expressed in a non integer type.
An exception to handle call of unwanted argument offset.
An exception to handle call of sqrt() when the rational is negative.
An exception to handle a rational who can't be expressed by the given type.
This class can be used to express rationals.
Definition: Rational.hpp:27
constexpr void verifyTemplateType() const
Verify if the template is correct. Throw an exception if the template is a floating point.
Definition: Rational.hpp:894
constexpr Rational< IntType > operator+=(const NonRationalType &nonRational)
Addition assignment operation between a rational and another type. Example: Rational += int.
Definition: Rational.hpp:564
constexpr friend Rational< IntType > operator*(const NonRationalType nonRational, const Rational< IntType > &rational)
Multiplication operation between a non-rational and a rational. Example: int * Rational.
Definition: Rational.hpp:259
constexpr friend bool operator<(const NonRationalType nonRational, const Rational< IntType > &rational)
< Comparison between a non-rational and a rational. Example: int < Rational
Definition: Rational.hpp:419
constexpr friend bool operator!=(const NonRationalType nonRational, const Rational< IntType > &rational)
Different comparison between a non-rational and a rational. Example: int != Rational.
Definition: Rational.hpp:382
static constexpr Rational< IntType > max(Rational< IntType > rational1, Rational< IntType > rational2) noexcept
Return the maximum between two rationals.
Definition: Rational.hpp:1124
constexpr Rational< IntType > cos() const
Give the cosine of a rational.
Definition: Rational.hpp:1065
constexpr bool operator>=(const NonRationalType &nonRational) const
>= Comparison between a rational and a non-rational. Example: Rational >= int
Definition: Rational.hpp:524
constexpr Rational< IntType > operator-(const NonRationalType &nonRational) const
Subtraction operation between a rational and another type. Example: Rational - int.
Definition: Rational.hpp:201
constexpr void setNumerator(IntType numerator)
Definition: Rational.hpp:114
static constexpr Rational< IntType > checkForOverflowThenReturn(const long long int numerator, const long long int denominator)
Check for overflow before returning a value.
Definition: Rational.hpp:919
constexpr Rational< IntType > operator/(const NonRationalType &nonRational) const
Division operation between a rational and another type. Example: Rational / int.
Definition: Rational.hpp:284
constexpr Rational< IntType > simplify() const noexcept
Simplify the Rational with GCD (called in constructor)
Definition: Rational.hpp:1087
bool isInteger() const noexcept
Definition: Rational.hpp:139
const IntType & operator[](const size_t &id) const
Getter with [] operator.
Definition: Rational.hpp:991
constexpr IntType toInteger() const noexcept
Get the integer part of the ratio.
Definition: Rational.hpp:818
constexpr bool operator==(const NonRationalType &nonRational) const
Comparison between a rational and a non-rational. Example: Rational == int.
Definition: Rational.hpp:327
bool isZero() const noexcept
Definition: Rational.hpp:144
constexpr bool operator>(const Rational< IntType > &anotherRational) const
> Comparison between 2 rationals
Definition: Rational.hpp:474
constexpr bool operator<=(const Rational< IntType > &anotherRational) const
<= Comparison between 2 rationals
Definition: Rational.hpp:435
bool isNegative() const noexcept
Definition: Rational.hpp:134
constexpr Rational< IntType > exp() const
Give the exponential of a rational.
Definition: Rational.hpp:1072
constexpr Rational< IntType > toApproximation(unsigned int digitsKept=Constant::DEFAULT_KEPT_DIGITS_APPROXIMATE) const
Get an approximation of a given Rational. We assume that you don't ask a bigger precision that you do...
Definition: Rational.hpp:1145
constexpr Rational< IntType > operator*(const NonRationalType &nonRational) const
Multiplication operation between a rational and another type. Example: Rational * int.
Definition: Rational.hpp:247
constexpr Rational< IntType > operator*=(const NonRationalType &nonRational)
Multiplication assignment operation between a rational and another type. Example: Rational * int.
Definition: Rational.hpp:634
constexpr bool operator<=(const NonRationalType &nonRational) const
<= Comparison between a rational and a non-rational. Example: Rational <= int
Definition: Rational.hpp:446
constexpr void verifyDenominator(IntType denominator, bool checkIfDenominatorIsNull=true)
Verify if the denominator is null or negative.
Definition: Rational.hpp:1195
constexpr Rational()
Instantiate an object without parameters.
Definition: Rational.hpp:38
constexpr bool operator!=(const NonRationalType &nonRational) const
Different comparison between a rational and a non-rational. Example: Rational != int.
Definition: Rational.hpp:370
constexpr void setDenominator(IntType denominator)
Definition: Rational.hpp:116
constexpr friend bool operator>=(const NonRationalType nonRational, const Rational< IntType > &rational)
>= Comparison between a non-rational and a rational. Example: int >= Rational
Definition: Rational.hpp:536
constexpr void operator++()
Increment operator.
Definition: Rational.hpp:576
constexpr friend Rational< IntType > operator/(const NonRationalType nonRational, const Rational< IntType > &rational)
Division operation between a non-rational and a rational. Example: int / Rational.
Definition: Rational.hpp:296
constexpr friend bool operator==(const NonRationalType nonRational, const Rational< IntType > &rational)
Comparison between a non-rational and a rational. Example: int == Rational.
Definition: Rational.hpp:339
static constexpr Rational< IntType > Infinite() noexcept
Return an approximation of +infinite in Rational Type.
Definition: Rational.hpp:799
constexpr Rational< IntType > sqrt() const
Give the square root of a rational.
Definition: Rational.hpp:1057
static constexpr Rational< IntType > Pi() noexcept
Return Pi in Rational Type.
Definition: Rational.hpp:793
constexpr Rational< IntType > operator+(const NonRationalType &nonRational) const
Addition operation between a rational and another type. Example: Rational + int.
Definition: Rational.hpp:164
constexpr static void print(const Rational< IntType > rational, Args... args) noexcept
Variadic: Print the values of various rationals.
Definition: Rational.hpp:872
constexpr friend Rational operator-(const Rational &rational)
Unary operator, allow to do -Rational.
Definition: Rational.hpp:225
constexpr Rational< IntType > inverse() const
Inverse a rational : a / b into b / a.
Definition: Rational.hpp:674
constexpr friend bool operator>(const NonRationalType nonRational, const Rational< IntType > &rational)
< Comparison between a non-rational and a rational. Example: int > Rational
Definition: Rational.hpp:497
constexpr Rational< IntType > operator-=(const NonRationalType &nonRational)
Subtraction assignment operation between a rational and another type. Example: Rational - int.
Definition: Rational.hpp:599
constexpr void operator--()
Decrement operator.
Definition: Rational.hpp:611
constexpr bool operator<(const Rational< IntType > &anotherRational) const
< Comparison between 2 rationals
Definition: Rational.hpp:398
constexpr bool operator!=(const Rational< IntType > &anotherRational) const
Different comparison between 2 rationals.
Definition: Rational.hpp:355
constexpr Rational< IntType > operator/=(const Rational< IntType > &anotherRational)
Division assignment operation between 2 rationals.
Definition: Rational.hpp:648
constexpr Rational< IntType > operator+=(const Rational< IntType > &anotherRational)
Addition assignment operation between 2 rationals.
Definition: Rational.hpp:552
constexpr IntType getLowerOperand() const noexcept
Definition: Rational.hpp:106
constexpr Rational< IntType > abs() const
Give the abs of a rational.
Definition: Rational.hpp:708
constexpr Rational< IntType > operator/=(const NonRationalType &nonRational)
Multiplication assignment operation between a rational and another type. Example: Rational * int.
Definition: Rational.hpp:660
~Rational()=default
Default Destructor.
constexpr bool operator>(const NonRationalType &nonRational) const
> Comparison between a rational and a non-rational. Example: Rational > int
Definition: Rational.hpp:485
constexpr bool operator<(const NonRationalType &nonRational) const
< Comparison between a rational and a non-rational. Example: Rational < int
Definition: Rational.hpp:409
static constexpr Rational< IntType > One() noexcept
Return one in Rational Type.
Definition: Rational.hpp:787
constexpr bool operator==(const Rational< IntType > &anotherRational) const
Comparison between 2 rationals.
Definition: Rational.hpp:312
constexpr IntType getDenominator() const noexcept
Definition: Rational.hpp:87
constexpr IntType getLargerOperand() const noexcept
Definition: Rational.hpp:99
constexpr Rational< IntType > operator-=(const Rational< IntType > &anotherRational)
Definition: Rational.hpp:587
constexpr FloatingType toRealNumber() const noexcept
Get an approximation floating point number of the ratio.
Definition: Rational.hpp:829
constexpr friend Rational< IntType > operator+(const NonRationalType nonRational, const Rational< IntType > &rational)
Addition operation between a non-rational and a rational. Example: int + Rational.
Definition: Rational.hpp:176
constexpr bool operator>=(const Rational< IntType > &anotherRational) const
>= Comparison between 2 rationals
Definition: Rational.hpp:513
static constexpr Rational< IntType > Zero() noexcept
Return zero in Rational Type.
Definition: Rational.hpp:781
static constexpr Rational< IntType > min(Rational< IntType > rational1, Rational< IntType > rational2) noexcept
Return the minimum between two rationals.
Definition: Rational.hpp:1103
constexpr void verifyNumberLargeness(Rational< AnotherIntType > &anotherRational) const
Verify if the operands are superior to the limit of IntType.
Definition: Rational.hpp:1183
static constexpr Rational< IntType > fromFloatingPoint(FloatingType floatingRatio, size_t iter=Constant::DEFAULT_ITERATIONS_FROM_FP)
A method who automatically set numerator and denominator to approach the float parameter.
constexpr Rational< IntType > operator*=(const Rational< IntType > &anotherRational)
Multiplication assignment operation between 2 rationals.
Definition: Rational.hpp:622
IntType m_numerator
Rational's numerator.
Definition: Rational.hpp:883
constexpr IntType getNumerator() const noexcept
Definition: Rational.hpp:85
constexpr friend Rational< IntType > operator-(const NonRationalType nonRational, const Rational< IntType > &rational)
Subtraction operation between a non-rational and a rational. Example: int - Rational.
Definition: Rational.hpp:213
std::string toString() const noexcept
Return ( numerator / denominator ) as a string.
Definition: Rational.hpp:838
constexpr Rational(const Rational< IntType > &reference)=default
Default copy constructor.
constexpr friend bool operator<=(const NonRationalType nonRational, const Rational< IntType > &rational)
<= Comparison between a non-rational and a rational. Example: int <= Rational
Definition: Rational.hpp:458
constexpr Rational< IntType > pow(const FloatingType &k) const
Give the power of a rational.
Definition: Rational.hpp:1080
constexpr static void print(const Rational< IntType > rational) noexcept
Print the value of a rational.
Definition: Rational.hpp:860
IntType m_denominator
Rational's denominator.
Definition: Rational.hpp:885
const unsigned int DEFAULT_ITERATIONS_FROM_FP
Default iterations used in the fromFloatingPoint recursive algorithm.
Definition: Constant.hpp:13
const unsigned int DEFAULT_MAX_DIGITS_APPROXIMATE
The max digits handled by the method toApproximation.
Definition: Constant.hpp:15
const unsigned int DEFAULT_KEPT_DIGITS_APPROXIMATE
The default precision set for toApproximation.
Definition: Constant.hpp:16
const double DEFAULT_THRESHOLD_FROM_FP
Default iterations used in the fromFloatingPoint recursive algorithm.
Definition: Constant.hpp:14
auto roundToWantedPrecision(const FloatingType value, const int precision=10e4)
Round a number for a wanted precision (the digits)
Definition: Utils.hpp:24
std::ostream & operator<<(std::ostream &stream, const ERational< FloatType > &rational)
<< operator override to allow std::cout
Definition: ERational.hpp:592