26 template<
typename IntType =
int>
50 bool willBeReduce =
true,
51 bool willDenominatorBeVerified =
true
59 template<
typename FloatingType>
60 constexpr explicit Rational(
const FloatingType &nonRational);
73 template<
typename AnotherIntType>
94 inline const IntType &
operator[](
const size_t &
id)
const;
99 [[maybe_unused]] [[nodiscard]]
constexpr inline IntType
getLargerOperand() const noexcept {
106 [[maybe_unused]] [[nodiscard]]
constexpr inline IntType
getLowerOperand() const noexcept {
163 template<
typename NonRationalType>
175 template<
typename NonRationalType>
177 const NonRationalType nonRational,
200 template<
typename NonRationalType>
212 template<
typename NonRationalType>
214 const NonRationalType nonRational,
246 template<
typename NonRationalType>
258 template<
typename NonRationalType>
260 const NonRationalType nonRational,
283 template<
typename NonRationalType>
295 template<
typename NonRationalType>
297 const NonRationalType nonRational,
326 template<
typename NonRationalType>
327 constexpr inline bool operator==(
const NonRationalType &nonRational)
const {
338 template<
typename NonRationalType>
340 const NonRationalType nonRational,
369 template<
typename NonRationalType>
370 constexpr inline bool operator!=(
const NonRationalType &nonRational)
const {
381 template<
typename NonRationalType>
383 const NonRationalType nonRational,
408 template<
typename NonRationalType>
409 constexpr inline bool operator<(
const NonRationalType &nonRational)
const {
return *this < Rational<IntType>(nonRational); }
418 template<
typename NonRationalType>
420 const NonRationalType nonRational,
445 template<
typename NonRationalType>
446 constexpr inline bool operator<=(
const NonRationalType &nonRational)
const {
447 return *this <= Rational<IntType>(nonRational);
457 template<
typename NonRationalType>
459 const NonRationalType nonRational,
484 template<
typename NonRationalType>
485 constexpr inline bool operator>(
const NonRationalType &nonRational)
const {
496 template<
typename NonRationalType>
498 const NonRationalType nonRational,
523 template<
typename NonRationalType>
524 constexpr inline bool operator>=(
const NonRationalType &nonRational)
const {
535 template<
typename NonRationalType>
537 const NonRationalType nonRational,
553 *
this = *
this + anotherRational;
563 template<
typename NonRationalType>
588 *
this = *
this - anotherRational;
598 template<
typename NonRationalType>
623 *
this = *
this * anotherRational;
633 template<
typename NonRationalType>
649 *
this = *
this / anotherRational;
659 template<
typename NonRationalType>
701 template<
typename FloatingType>
727 [[maybe_unused]] [[nodiscard]] constexpr static
Rational<IntType>
min(
739 template<typename ...Args>
740 [[maybe_unused]] [[nodiscard]] constexpr static
Rational<IntType>
min(
755 [[maybe_unused]] [[nodiscard]] constexpr static
Rational<IntType>
max(
767 template<typename ...Args>
768 [[maybe_unused]] [[nodiscard]] constexpr static
Rational<IntType>
max(
818 [[nodiscard]]
inline constexpr IntType
toInteger() const noexcept {
819 assert(
getDenominator() != 0 &&
"This denominator shouldn't never be equal to 0");
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");
838 [[nodiscard]]
inline std::string
toString() const noexcept {
849 template<
typename FloatingType =
double>
851 FloatingType floatingRatio,
861 std::cout << rational.toString() << std::endl << std::endl;
871 template<
typename... Args>
873 std::cout << rational.toString() << std::endl;
903 constexpr void verifyDenominator(IntType denominator,
bool checkIfDenominatorIsNull =
true);
910 template<
typename AnotherIntType>
920 const long long int numerator,
921 const long long int denominator
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) {
951 if (willBeReduce) *
this =
simplify();
956 template<
typename IntType>
957 template<
typename FloatingType>
959 verifyTemplateType();
961 if (std::is_integral<FloatingType>()) {
979 template<
typename IntType>
980 template<
typename AnotherIntType>
982 : m_numerator(copiedRational.getNumerator()), m_denominator(copiedRational.getDenominator()){
990 template<
typename IntType>
992 if (
id == 0)
return getNumerator();
993 else if (
id == 1)
return getDenominator();
997 template<
typename IntType>
999 if (
id == 0)
return m_numerator;
1000 else if (
id == 1)
return m_denominator;
1008 template<
typename IntType>
1011 static_cast<long long int>(getNumerator()) * anotherRational.
getDenominator() + getDenominator() * anotherRational.
getNumerator(),
1012 static_cast<long long int>(getDenominator()) * anotherRational.
getDenominator()
1020 template<
typename IntType>
1023 static_cast<long long int>(getNumerator()) * anotherRational.
getDenominator() - getDenominator() * anotherRational.
getNumerator(),
1024 static_cast<long long int>(getDenominator()) * anotherRational.
getDenominator()
1032 template<
typename IntType>
1035 static_cast<long long int>(getNumerator()) * anotherRational.
getNumerator(),
1036 static_cast<long long int>(getDenominator()) * anotherRational.
getDenominator()
1044 template<
typename IntType>
1047 static_cast<long long int>(getNumerator()) * anotherRational.
getDenominator(),
1048 static_cast<long long int>(getDenominator()) * anotherRational.
getNumerator()
1056 template<
typename IntType>
1060 std::sqrt(
static_cast<double>(getNumerator()) / getDenominator())
1064 template<
typename IntType>
1067 std::cos(
static_cast<double>(getNumerator()) / getDenominator())
1071 template<
typename IntType>
1074 std::exp(
static_cast<double>(getNumerator()) / getDenominator())
1078 template<
typename IntType>
1079 template<
typename FloatingType>
1082 std::pow(
static_cast<double>(getNumerator()) / getDenominator(), k)
1086 template<
typename IntType>
1088 const int gcd = std::gcd(getNumerator(), getDenominator());
1089 assert(gcd != 0 &&
"GCD shouldn't be equal to 0");
1092 getNumerator() / gcd,
1093 getDenominator() / gcd,
1102 template<
typename IntType>
1107 return rational1 < rational2 ? rational1 : rational2;
1110 template<
typename IntType>
1111 template<
typename... Args>
1116 return min(rational, min(args...));
1123 template<
typename IntType>
1128 return rational1 < rational2 ? rational2 : rational1;
1131 template<
typename IntType>
1132 template<
typename... Args>
1137 return max(rational, max(args...));
1144 template<
typename IntType>
1150 template<
typename IntType>
1151 template<
typename FloatingType>
1153 const FloatingType floatingRatio,
1156 constexpr FloatingType ZERO = 0;
1157 constexpr FloatingType ONE = 1;
1159 if (floatingRatio < ZERO) {
1160 return -fromFloatingPoint(-floatingRatio, iter);
1167 if (floatingRatio < ONE) {
1168 assert(floatingRatio != 0 &&
"floatingRatio shouldn't never be equal to 0 here");
1169 return fromFloatingPoint(ONE / floatingRatio, iter).inverse();
1172 auto integerPart =
static_cast<IntType
>(floatingRatio);
1173 return fromFloatingPoint(floatingRatio - integerPart, iter - 1)
1181 template<
typename IntType>
1182 template<
typename AnotherIntType>
1187 if ((std::numeric_limits<IntType>::max() < anotherRational.
getLargerOperand() ||
1188 std::numeric_limits<IntType>::lowest() > anotherRational.
getLowerOperand())) {
1194 template<
typename IntType>
1196 const IntType denominator,
1197 const bool checkIfDenominatorIsNull
1199 constexpr IntType ZERO = 0;
1200 if (denominator == ZERO && checkIfDenominatorIsNull)
1203 if (denominator < ZERO) {
1204 m_numerator = -m_numerator;
1205 m_denominator = -denominator;
1220 template<
typename IntType>
1222 return stream << rational.
toString();
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.
This class can be used to express rationals.
constexpr void verifyTemplateType() const
Verify if the template is correct. Throw an exception if the template is a floating point.
constexpr Rational< IntType > operator+=(const NonRationalType &nonRational)
Addition assignment operation between a rational and another type. Example: Rational += int.
constexpr friend Rational< IntType > operator*(const NonRationalType nonRational, const Rational< IntType > &rational)
Multiplication operation between a non-rational and a rational. Example: int * Rational.
constexpr friend bool operator<(const NonRationalType nonRational, const Rational< IntType > &rational)
< Comparison between a non-rational and a rational. Example: int < Rational
constexpr friend bool operator!=(const NonRationalType nonRational, const Rational< IntType > &rational)
Different comparison between a non-rational and a rational. Example: int != Rational.
static constexpr Rational< IntType > max(Rational< IntType > rational1, Rational< IntType > rational2) noexcept
Return the maximum between two rationals.
constexpr Rational< IntType > cos() const
Give the cosine of a rational.
constexpr bool operator>=(const NonRationalType &nonRational) const
>= Comparison between a rational and a non-rational. Example: Rational >= int
constexpr Rational< IntType > operator-(const NonRationalType &nonRational) const
Subtraction operation between a rational and another type. Example: Rational - int.
constexpr void setNumerator(IntType numerator)
static constexpr Rational< IntType > checkForOverflowThenReturn(const long long int numerator, const long long int denominator)
Check for overflow before returning a value.
constexpr Rational< IntType > operator/(const NonRationalType &nonRational) const
Division operation between a rational and another type. Example: Rational / int.
constexpr Rational< IntType > simplify() const noexcept
Simplify the Rational with GCD (called in constructor)
bool isInteger() const noexcept
const IntType & operator[](const size_t &id) const
Getter with [] operator.
constexpr IntType toInteger() const noexcept
Get the integer part of the ratio.
constexpr bool operator==(const NonRationalType &nonRational) const
Comparison between a rational and a non-rational. Example: Rational == int.
bool isZero() const noexcept
constexpr bool operator>(const Rational< IntType > &anotherRational) const
> Comparison between 2 rationals
constexpr bool operator<=(const Rational< IntType > &anotherRational) const
<= Comparison between 2 rationals
bool isNegative() const noexcept
constexpr Rational< IntType > exp() const
Give the exponential of a rational.
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...
constexpr Rational< IntType > operator*(const NonRationalType &nonRational) const
Multiplication operation between a rational and another type. Example: Rational * int.
constexpr Rational< IntType > operator*=(const NonRationalType &nonRational)
Multiplication assignment operation between a rational and another type. Example: Rational * int.
constexpr bool operator<=(const NonRationalType &nonRational) const
<= Comparison between a rational and a non-rational. Example: Rational <= int
constexpr void verifyDenominator(IntType denominator, bool checkIfDenominatorIsNull=true)
Verify if the denominator is null or negative.
constexpr Rational()
Instantiate an object without parameters.
constexpr bool operator!=(const NonRationalType &nonRational) const
Different comparison between a rational and a non-rational. Example: Rational != int.
constexpr void setDenominator(IntType denominator)
constexpr friend bool operator>=(const NonRationalType nonRational, const Rational< IntType > &rational)
>= Comparison between a non-rational and a rational. Example: int >= Rational
constexpr void operator++()
Increment operator.
constexpr friend Rational< IntType > operator/(const NonRationalType nonRational, const Rational< IntType > &rational)
Division operation between a non-rational and a rational. Example: int / Rational.
constexpr friend bool operator==(const NonRationalType nonRational, const Rational< IntType > &rational)
Comparison between a non-rational and a rational. Example: int == Rational.
static constexpr Rational< IntType > Infinite() noexcept
Return an approximation of +infinite in Rational Type.
constexpr Rational< IntType > sqrt() const
Give the square root of a rational.
static constexpr Rational< IntType > Pi() noexcept
Return Pi in Rational Type.
constexpr Rational< IntType > operator+(const NonRationalType &nonRational) const
Addition operation between a rational and another type. Example: Rational + int.
constexpr static void print(const Rational< IntType > rational, Args... args) noexcept
Variadic: Print the values of various rationals.
constexpr friend Rational operator-(const Rational &rational)
Unary operator, allow to do -Rational.
constexpr Rational< IntType > inverse() const
Inverse a rational : a / b into b / a.
constexpr friend bool operator>(const NonRationalType nonRational, const Rational< IntType > &rational)
< Comparison between a non-rational and a rational. Example: int > Rational
constexpr Rational< IntType > operator-=(const NonRationalType &nonRational)
Subtraction assignment operation between a rational and another type. Example: Rational - int.
constexpr void operator--()
Decrement operator.
constexpr bool operator<(const Rational< IntType > &anotherRational) const
< Comparison between 2 rationals
constexpr bool operator!=(const Rational< IntType > &anotherRational) const
Different comparison between 2 rationals.
constexpr Rational< IntType > operator/=(const Rational< IntType > &anotherRational)
Division assignment operation between 2 rationals.
constexpr Rational< IntType > operator+=(const Rational< IntType > &anotherRational)
Addition assignment operation between 2 rationals.
constexpr IntType getLowerOperand() const noexcept
constexpr Rational< IntType > abs() const
Give the abs of a rational.
constexpr Rational< IntType > operator/=(const NonRationalType &nonRational)
Multiplication assignment operation between a rational and another type. Example: Rational * int.
~Rational()=default
Default Destructor.
constexpr bool operator>(const NonRationalType &nonRational) const
> Comparison between a rational and a non-rational. Example: Rational > int
constexpr bool operator<(const NonRationalType &nonRational) const
< Comparison between a rational and a non-rational. Example: Rational < int
static constexpr Rational< IntType > One() noexcept
Return one in Rational Type.
constexpr bool operator==(const Rational< IntType > &anotherRational) const
Comparison between 2 rationals.
constexpr IntType getDenominator() const noexcept
constexpr IntType getLargerOperand() const noexcept
constexpr Rational< IntType > operator-=(const Rational< IntType > &anotherRational)
constexpr FloatingType toRealNumber() const noexcept
Get an approximation floating point number of the ratio.
constexpr friend Rational< IntType > operator+(const NonRationalType nonRational, const Rational< IntType > &rational)
Addition operation between a non-rational and a rational. Example: int + Rational.
constexpr bool operator>=(const Rational< IntType > &anotherRational) const
>= Comparison between 2 rationals
static constexpr Rational< IntType > Zero() noexcept
Return zero in Rational Type.
static constexpr Rational< IntType > min(Rational< IntType > rational1, Rational< IntType > rational2) noexcept
Return the minimum between two rationals.
constexpr void verifyNumberLargeness(Rational< AnotherIntType > &anotherRational) const
Verify if the operands are superior to the limit of IntType.
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.
IntType m_numerator
Rational's numerator.
constexpr IntType getNumerator() const noexcept
constexpr friend Rational< IntType > operator-(const NonRationalType nonRational, const Rational< IntType > &rational)
Subtraction operation between a non-rational and a rational. Example: int - Rational.
std::string toString() const noexcept
Return ( numerator / denominator ) as a string.
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
constexpr Rational< IntType > pow(const FloatingType &k) const
Give the power of a rational.
constexpr static void print(const Rational< IntType > rational) noexcept
Print the value of a rational.
IntType m_denominator
Rational's denominator.
const unsigned int DEFAULT_ITERATIONS_FROM_FP
Default iterations used in the fromFloatingPoint recursive algorithm.
const unsigned int DEFAULT_MAX_DIGITS_APPROXIMATE
The max digits handled by the method toApproximation.
const unsigned int DEFAULT_KEPT_DIGITS_APPROXIMATE
The default precision set for toApproximation.
const double DEFAULT_THRESHOLD_FROM_FP
Default iterations used in the fromFloatingPoint recursive algorithm.
std::ostream & operator<<(std::ostream &stream, const ERational< FloatType > &rational)
<< operator override to allow std::cout