user2108150
user2108150

Reputation:

Why not use an extended rational instead of floats/doubles?

Why not use extended rationals for floating point representations?

The idea is that computers are discrete, such that true irrational variables can not be represented by the float or double type. In fact, I would argue that any finite sequence of digits constituting a float has a rational synonym. Even some infinite sequences have this property. Therefore, why not use rationals? It appears to be easier, especially to support larger numbers. Am I being naive here? Why do we need floats over a (partial) rational implementation?

#include <iostream>

class Rational
{
public:
    Rational (int numerator, int denominator, int exponent)
    :
        m_numerator(numerator),
        m_denominator(denominator),
        m_exponent(exponent)
    {}

    friend Rational operator* (const Rational &lhs, const Rational &rhs);
    friend std::ostream &operator<< (std::ostream &os, const Rational &out);

private:

    int m_numerator, m_denominator, m_exponent;
};

Rational operator* (const Rational &lhs, const Rational &rhs)
{
    Rational tmp = lhs;
    tmp.m_numerator *= rhs.m_numerator;
    tmp.m_denominator *= rhs.m_denominator;
    tmp.m_exponent += rhs.m_exponent;
    return tmp;
}

std::ostream &operator<< (std::ostream &os, const Rational &out)
{
    os << out.m_numerator << "/" << out.m_denominator << "E" << out.m_exponent;
    return os;
}

int main ( int argc, char *argv[] )
{
    Rational a(1, 3, 10), b(4, 7, -5);
    Rational c = a * b;
    std::cout << c << std::endl;
}

Edit:

This is merely an example. In any real scenario, something like GMP rationals would be applied. These rationals canonicalize the rational to its lowest form.

Upvotes: 2

Views: 527

Answers (1)

Patricia Shanahan
Patricia Shanahan

Reputation: 26185

There are three main reasons "why not". If none of them apply, a rational number system may be useful for your application:

  1. Compactness. It only takes 8 bytes to store a double, 4 bytes for a float. The is not important if you are dealing with one or two of them. It does matter for matrices with thousands of rows and columns.
  2. Performance. As Pascal Cuoq pointed out in a comment on the question, many important floating point operations are very fast on modern computers.
  3. Need to approximate irrational numbers such as pi and the values of functions such as square root and the trig functions. If you need to deal with rounding anyway, general rational numbers lose a lot of their attraction. Floating point numbers are, of course, rational, but with carefully designed rounding implemented in fast hardware.

If you think your Rational class has usable compactness and performance for scientific and engineering work, I think you should use it to run the LINPACK benchmarks, especially LINPACK 1000, and post your results for comparison to results for similar systems using floating point arithmetic. LINPACK 1000 times solving a system of 1000 simultaneous linear equations

Upvotes: 7

Related Questions