Я создал следующий класс рациональных чисел C++ со всеми общими арифметическими функциями (+
, -
, *
, /
, ==
и !=
).
template <class T>
struct rationalNumber
{
static_assert(!std::numeric_limits<T>::is_signed, "ERROR: Type T must be unsigned");
static_assert(std::is_integral<T>::value, "ERROR: Type T must be integral");
T numerator;
T denominator;
bool sign;
rationalNumber(const int n = 0) : numerator(std::abs(n)), denominator(1), sign(std::signbit(n)) {}
rationalNumber(const T n, const T d, const bool s = false) : numerator(n), denominator(d), sign(s) {}
rationalNumber(const rationalNumber&) = default;
rationalNumber& operator=(const rationalNumber&) = default;
rationalNumber operator-() const
{
return rationalNumber(numerator, denominator, !sign);
}
void reduce()
{
T divisor = gcd(numerator, denominator);
if (divisor != 1)
{
numerator /= divisor;
denominator /= divisor;
}
else if (numerator == 0)
{
denominator = 1;
sign = false;
}
assert(denominator != 0);
}
};
using RN = rationalNumber<unsigned long long>;
Возможно ли реализовать оставшиеся операторы отношений (<
, >
, <=
, >=
) с использованием арифметики с плавающей запятой, или это приведет к результатам, подверженным ошибкам?
Обратите внимание, что я рассматривал только числа с плавающей запятой, так как перекрестное умножение во многих случаях может привести к целочисленному переполнению.
T
равноint64_t
, у нас будет до 19 цифр, аdouble
подойдет для 15 или 16... так что ясно, что иногда у вас могут быть проблемы. - person Tony Delroy   schedule 16.02.2015