Сравнение рациональных чисел

Я сделал следующий класс 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>;

Реально ли реализовать оставшиеся операторы реляционных операторов (<, >, <=, >=) с использованием арифметики с плавающей запятой, или это приведет к ошибочным результатам?

Обратите внимание, что я рассмотрел только числа с плавающей запятой, поскольку перекрестное умножение во многих случаях может привести к переполнению целых чисел.

3

Решение

Да, выполнимо реализовать тест на неравенство, используя операции с плавающей запятой. И, да, это потенциально даст «подверженные ошибкам результаты» из-за конечной точности с плавающей запятой.

На самом деле нет необходимости использовать плавающую точку вообще. Математически тест «a / b> c / d» (при условии, что a, b, c, d положительны) эквивалентен тесту «aд> бc «. С переменными без знака вам также нужно будет учесть (или обойти) эффекты арифметики по модулю (я оставлю это в качестве упражнения), но вполне реально реализовать тест без использования плавающей запятой в все.

4

Другие решения


По вопросам рекламы [email protected]