Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing Rational Numbers

I have made the following rational numbers C++ class with all the general arithmetic functions (+, -, *, /, == and !=).

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>;

Is it feasible to implement the remaining relational operators operators (<, >, <=, >=) using floating point arithmetic, or will that lead to error prone results?

Note that I have only considered floating points since cross multiplying could in many cases lead to integer overflow.

like image 443
Jonas Avatar asked Jul 17 '26 19:07

Jonas


1 Answers

Yes, it is feasible to implement the test for inequality using floating point operations. And, yes, that will potentially give "error prone results" due to finite precision of floating point.

It is not actually necessary to use floating point at all. Mathematically, a test of "a/b > c/d" (assuming a,b,c,d are positive) is equivalent to the test "ad > bc". With unsigned variables, you will also need to account for (or work around) the effects of modulo arithmetic (I'll leave doing that as an exercise) but it is quite feasible to implement the test exactly without using floating point at all.

like image 77
Rob Avatar answered Jul 20 '26 08:07

Rob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!