rational_add.hpp

Back to Rational numbers

pastel/sys/rational/

#ifndef PASTELSYS_RATIONAL_ADD_HPP
#define PASTELSYS_RATIONAL_ADD_HPP

#include "pastel/sys/rational/rational.h"

namespace Pastel
{

    template <typename Integer>
    Rational<Integer>& Rational<Integer>::operator+=(
        Rational that)
    {
        /*
       +   |   Num NaN +oo -oo +0 -0
       ---+-------------------------
       Num|    Num
       NaN|    NaN NaN
       +oo|    +oo NaN +oo
       -oo|    -oo NaN NaN -oo
       +0 |    Num NaN +oo -oo +0
       -0 |    Num NaN +oo -oo
       */

        NumberType thisType = classify();
        NumberType thatType = that.classify();

        Rational result;

        if (thisType == NumberType::Nan ||
            thatType == NumberType::Nan ||
            (thisType == NumberType::Infinity &&
            thatType == NumberType::MinusInfinity) ||
            (thisType == NumberType::MinusInfinity &&
            thatType == NumberType::Infinity))
        {
            // The result is NaN.
            result.set(0, 0, SkipSimplify());
        }
        else if (
            thisType == NumberType::Infinity ||
            thatType == NumberType::Infinity)
        {
            // The result is +oo.
            result.set(1, 0, SkipSimplify());
        }
        else if (
            thisType == NumberType::MinusInfinity ||
            thatType == NumberType::MinusInfinity)
        {
            // The result is -oo.
            result.set(-1, 0, SkipSimplify());
        }
        else
        {
            // Both are just normal numbers.
            result.set(
                m() * that.n() +
                that.m() * n(),
                n() * that.n());
        }

        swap(result);

        return *this;
    }

    template <typename Integer>
    Rational<Integer> Rational<Integer>::operator+() const
    {
        return *this;
    }

    template <typename Integer>
    Rational<Integer>& Rational<Integer>::operator-=(
        Rational that)
    {
        return (*this) +=
            Rational(
            -that.m_, std::move(that.n_));
    }

    template <typename Integer>
    Rational<Integer> Rational<Integer>::operator-() const
    {
        return Rational(-m_, n_);
    }

}

#endif