C++ 实数类

这是一堆我自己写完都怀疑人生的代码。
或许我见识太少了吧……

实现一个实数类。这个类也可以看作是分数类。实现了基本的四则运算和比较。另外,与整数或小数的转换还没有实现,无限循环小数转分数也暂时没有实现。但我早晚会写的。。。
咕咕咕。
这里的重头戏是模版。
啊……模版,我边学边卖,才知道模版还可以这么玩。
这次只有一个文件……
来体会一下来自C++的恐惧吧!

注意:以下代码没有经过严谨测试及性能优化。

BUGFIX:
1. 修复operator=不能对自身影响的BUG;(2018.10.10)
2.修复小数转分数时,造成整数溢出的BUG;(2018.10.10)

Rational.h

#pragma once
#include "stdinc.h"

namespace Lunacia
{
    class __Rational {};

    template<typename NumT = int>
    class Rational final : public __Rational
    {
    public:
        Rational();

        template<typename NumT2>
        Rational(const Rational<NumT2>& ra); 

        Rational(NumT numer, NumT denom);
        Rational(NumT numer, NumT denom, bool isDenomFixed);
        ~Rational();

    public:
        static NumT Gcd(NumT a, NumT b);
        static NumT Lcm(NumT a, NumT b);

        static bool IsEven(NumT num);
        static NumT GetSymbol(NumT num);

        static bool IsEqualFloating(long double a, long double b);

        void SetDenomFixed(bool isFix);
        bool GetDenomFixed() const;

        void GetRationalString(std::string& __out resStr) const;
        void GetRationalString(std::wstring& __out resStr) const;

    public:
        ///operator+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        template<typename ParamT,
            typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type * = nullptr>
            Rational<NumT> operator +(const ParamT rRational) const;

        template<typename ParamT,
            typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
            Rational<NumT> operator +(const ParamT& rRational) const;

        Rational<NumT> operator +(const Rational& rRational) const;

        ///operator-----------------------------------------------------------------------
        template<typename ParamT,
            typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type * = nullptr>
        Rational<NumT> operator -(const ParamT& rRational) const;

        template<typename ParamT,
            typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
            Rational<NumT> operator -(const ParamT& rRational) const;

        Rational<NumT> operator -(const Rational& rRational) const;

        ///operator******************************************************
        template<typename ParamT,
            typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type * = nullptr>
            Rational<NumT> operator *(const ParamT& rRational) const;

        template<typename ParamT,
            typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
            Rational<NumT> operator *(const ParamT& rRational) const;

        Rational<NumT> operator *(const Rational& rRational) const;
        
        ///operator///////////////////////////////////////////////////////
        template<typename ParamT,
            typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type * = nullptr>
            Rational<NumT> operator /(const ParamT& rRational) const;

        template<typename ParamT,
            typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
            Rational<NumT> operator /(const ParamT& rRational) const;

        Rational<NumT> operator /(const Rational& rRational) const;

        ///operator=======================================================
        template<typename ParamT,
            typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type * = nullptr>
            Rational<NumT> operator =(const ParamT& rRational);

        template<typename ParamT,
            typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
            Rational<NumT> operator =(const ParamT& rRational);

        Rational<NumT> operator =(const Rational& rRational);

        ///operator== == == == == == == == == == == == == == == == == == == == == == ==
        template<typename ParamT,
            typename  std::enable_if < 
                std::is_integral <ParamT> ::value || 
                    std::is_base_of<__Rational, ParamT>::value,
                ParamT 
            > ::type * = nullptr>
            bool operator ==(const ParamT& rRational) const;

        template<typename ParamT,
            typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
            bool operator ==(const ParamT& rRational) const;
        
        ///operator!= != != != != != != != != != != != != != != != != != != != != != != != != != != != != 
        template<typename ParamT,
            typename  std::enable_if <
                std::is_integral <ParamT> ::value ||
                    std::is_floating_point <ParamT> ::value||
                    std::is_base_of<__Rational, ParamT>::value,
                ParamT
            > ::type * = nullptr>
            bool operator !=(const ParamT& rRational) const;

        ///operator>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        template<typename ParamT,
            typename  std::enable_if <
                    std::is_integral <ParamT> ::value ||
                    std::is_floating_point <ParamT> ::value ||
                    std::is_base_of<__Rational, ParamT>::value,
                ParamT
            > ::type * = nullptr>
            bool operator >(const ParamT& rRational) const;

        ///operator <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        template<typename ParamT,
            typename  std::enable_if <
                std::is_integral <ParamT> ::value ||
                    std::is_floating_point <ParamT> ::value ||
                    std::is_base_of<__Rational, ParamT>::value,
                ParamT
            > ::type * = nullptr>
        bool operator <(const ParamT& rRational) const ;

        ///operator >= >= >= >= >= >= >= >= >= >= >= >= >= >= >= >= >= >= >= >= 
        template<typename ParamT,
            typename  std::enable_if <
                std::is_integral <ParamT> ::value ||
                    std::is_floating_point <ParamT> ::value ||
                    std::is_base_of<__Rational, ParamT>::value,
                ParamT> ::type * = nullptr>
        bool operator >=(const ParamT& rRational);

        ///operator <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= 
        template<typename ParamT,
            typename  std::enable_if <
                std::is_integral <ParamT> ::value ||
                    std::is_floating_point <ParamT> ::value ||
                    std::is_base_of<__Rational, ParamT>::value,
            ParamT> ::type * = nullptr>
        bool operator <=(const ParamT& rRational);
        
        ///operator+= += += += += += += += += += += += += += += += += += += 
        template<typename ParamT,
            typename  std::enable_if <
                std::is_integral <ParamT> ::value ||
                    std::is_floating_point <ParamT> ::value ||
                    std::is_base_of<__Rational, ParamT>::value,
            ParamT> ::type * = nullptr>
            Rational<NumT> operator +=(const ParamT& rRational);

        ///operator-= -= -= -= -= -= -= -= -= -= -= -= -= -= -= -= -= -= -= -= 
        template<typename ParamT,
            typename  std::enable_if <
                std::is_integral <ParamT> ::value ||
                    std::is_floating_point <ParamT> ::value ||
                    std::is_base_of<__Rational, ParamT>::value,
            ParamT> ::type * = nullptr>
            Rational<NumT> operator -=(const ParamT& rRational);

        ///operator*= *= *= *= *= *= *= *= *= *= *= *= *= *= *= *= *= *= 
        template<typename ParamT,
            typename  std::enable_if <
                std::is_integral <ParamT> ::value ||
                    std::is_floating_point <ParamT> ::value ||
                    std::is_base_of<__Rational, ParamT>::value,
            ParamT> ::type * = nullptr>
            Rational<NumT> operator *=(const ParamT& rRational);

        ///operator/= /= /= /= /= /= /= /= /= /= /= /= /= /= /= /= /= /= 
        template<typename ParamT,
            typename  std::enable_if <
                std::is_integral <ParamT> ::value ||
                    std::is_floating_point <ParamT> ::value ||
                    std::is_base_of<__Rational, ParamT>::value,
            ParamT> ::type * = nullptr>
            Rational<NumT> operator /=(const ParamT& rRational);

        ///CHECK IT : 
        template<typename ParamT,
            typename  std::enable_if <
                    std::is_floating_point <ParamT> ::value,
            ParamT> ::type * = nullptr>
            operator ParamT();

        ///CHECK IT : 
        template<typename ParamT,
            typename  std::enable_if <
                std::is_integral <ParamT> ::value,
            ParamT> ::type * = nullptr>
            operator ParamT();

        ///operator() () () () () () () () () () () () () () () () () () () () () () () () 
        void operator ()(const NumT& newNumer, const NumT& newDenmo);
        void operator ()(const Rational& newRa);

    public:
        void Reciprocal();
        static void Reciprocal(Rational<NumT>& __out res);
        
        NumT Reduction(Rational& other);        /*Return new denom.*/
        static NumT Reduction(Rational& raA, Rational& raB);

        void DenomFix(bool isForce = false);

        template<typename ParamT, typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type * = nullptr>
        static void FloatingToRational(const ParamT& num, Rational<NumT>& res);

    public:
        NumT _denom, _numer;

    private:
        bool m_isDenomFixed;
    };

    ////////////////////////////////////////////////////////////////////////////
    template<typename NumT>
    Rational<NumT>::Rational(NumT numer, NumT denom) :
        Rational(numer, denom, false)
    {
    }

    template<typename NumT>
    Rational<NumT>::Rational(NumT numer, NumT denom, bool isDenomFixed) :
        _denom(denom),
        _numer(numer),
        m_isDenomFixed(isDenomFixed)
    {
        static_assert(std::is_integral<NumT>::value, "[Error] Error Number Type, Must be an integer.");
        DenomFix();
    }

    template<typename NumT>
    Rational<NumT>::Rational() :
        Rational(0, 1, false)
    {
    }


    template<typename NumT>
    Rational<NumT>::~Rational()
    {
    }

    template<typename NumT>
    NumT Rational<NumT>::Gcd(NumT x, NumT y)
    {
        static_assert(std::is_integral<NumT>::value, "[Error] Error Number Type, Must be an integer.");

        if (x < 0 || y < 0)
        {
            return -1;
        }

        if (x < y) return Gcd(y, x);

        if (y == 0) return x;

        if (IsEven(x))
        {
            if (IsEven(y))
                return (Gcd(x >> 1, y >> 1) << 1);
            else
                return Gcd(x >> 1, y);
        }
        else
        {
            if (IsEven(y))
                return Gcd(x, y >> 1);
            else
                return Gcd(y, x - y);
        }
    }

    template<typename NumT>
    NumT Rational<NumT>::Lcm(NumT a, NumT b)
    {
        static_assert(std::is_integral<NumT>::value, "[Error] Error Number Type, Must be an integer.");

        NumT max = (a > b) ? a : b;
        NumT min = a + b - max;
        NumT lcm = -1;
        for (NumT i = 1; i <= min; ++i)
        {
            lcm = max * i;
            if (lcm % min == 0)
            {
                break;
            }
        }
        return lcm;
    }

    template<typename NumT>
    inline bool Rational<NumT>::IsEven(NumT num)
    {
        static_assert(std::is_integral<NumT>::value, "[Error] Error Number Type, Must be an integer.");
        return (num & 1) == 0;
    }

    template<typename NumT>
    inline NumT Rational<NumT>::GetSymbol(NumT num)
    {
        if (num == 0) return 0;
        return num / std::abs(num);
    }

    template<typename NumT>
    inline bool Rational<NumT>::IsEqualFloating(long double a, long double b)
    {
        return std::abs(a - b) < DoubleESP;
    }

    template<typename NumT>
    void Rational<NumT>::SetDenomFixed(bool isFix)
    {
        m_isDenomFixed = isFix;
        DenomFix();
    }

    template<typename NumT>
    inline bool Rational<NumT>::GetDenomFixed() const 
    {
        return m_isDenomFixed;
    }

    template<typename NumT>
    void Rational<NumT>::GetRationalString(std::string & resStr) const
    {
        resStr = std::to_string(_numer) + " / " + std::to_string(_denom);
    }

    template<typename NumT>
    void Rational<NumT>::GetRationalString(std::wstring & resStr) const
    {
        resStr = std::to_wstring(_numer) + L" / " + std::to_wstring(_denom);
    }

    template<typename NumT>
    inline void Rational<NumT>::Reciprocal()
    {
        std::swap(_numer, _denom);
    }

    template<typename NumT>
    inline static void Rational<NumT>::Reciprocal(Rational<NumT>& res)
    {
        res(_denom, _numer);
    }

    template<typename NumT>
    inline void Rational<NumT>::DenomFix(bool isForce)
    {
        if (m_isDenomFixed || isForce)
        {
            NumT gcd = Rational<NumT>::Gcd(_numer, _denom);
            if (gcd == -1)
            {
                //WarningThrow("Return gcd is -1. m_numer or m_denom is 0.");
                return;
            }
            _denom /= gcd;
            _numer /= gcd;
        }

        if (_denom < 0)
        {
            _denom *= -1;
            _numer *= -1;
        }
    }

    template<typename NumT>
    NumT Rational<NumT>::Reduction(Rational& other)
    {
        NumT lcm = Rational<NumT>::Lcm(_denom, other._denom);
        
        _numer *= lcm / _denom;
        _denom = lcm;
        
        other._numer *= lcm / other._denom;
        other._denom = lcm;

        return lcm;
    }

    template<typename NumT>
    inline NumT Rational<NumT>::Reduction(Rational & raA, Rational & raB)
    {
        raA.Reduction(raB);
        return raA._denom;
    }

    template<typename NumT>
    template<typename NumT2>
    Rational<NumT>::Rational(const Rational<NumT2>& ra)
    {
        _denom = static_cast<NumT>(ra._denom);
        _numer = static_cast<NumT>(ra._numer);
        SetDenomFixed(ra.GetDenomFixed());
        //(*this)(ra);      //Error: Recursive forever. 
    }

    ///operator+
    template<typename NumT>
    template<typename ParamT, typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type *>
    inline Rational<NumT> Rational<NumT>::operator+(const ParamT rRational) const
    {
        Rational<NumT> resRa(_numer + static_cast<NumT>(rRational) * _denom, _denom);
        resRa.SetDenomFixed(m_isDenomFixed);
        return resRa;
    }

    template<typename NumT>
    template<typename ParamT, typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type *>
    inline Rational<NumT> Rational<NumT>::operator+(const ParamT & rRational) const
    {
        Rational<int64_t> rightVal;
        FloatingToRational(rRational, rightVal);

        return rightVal + *this;
    }
    
    template<typename NumT>
    inline Rational<NumT> Rational<NumT>::operator+(const Rational & rRational) const 
    {
        Rational rightVal = rRational;
        Rational<NumT> resRa(*this);
        Reduction(rightVal, resRa);

        resRa._numer += rightVal._numer;
        resRa.SetDenomFixed(m_isDenomFixed);
        return resRa;
    }

    ///operator-
    template<typename NumT>
    template<typename ParamT, typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type *>
    inline Rational<NumT> Rational<NumT>::operator-(const ParamT & rRational) const 
    {
        Rational<NumT> resRa(_numer - static_cast<NumT>(rRational) * _denom, _denom);

        resRa.SetDenomFixed(m_isDenomFixed);
        return resRa;
    }

    template<typename NumT>
    template<typename ParamT, typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type *>
    inline Rational<NumT> Rational<NumT>::operator-(const ParamT & rRational) const
    {
        Rational<int64_t> rightVal;

        FloatingToRational(rRational, rightVal);
        Rational<NumT> resRa(*this);

        return resRa - rightVal;
    }

    template<typename NumT>
    inline Rational<NumT> Rational<NumT>::operator-(const Rational & rRational) const
    {
        Rational rightVal = rRational;
        Rational<NumT> resRa(*this);

        Reduction(rightVal, resRa);
        resRa._numer -= rightVal._numer;

        resRa.SetDenomFixed(m_isDenomFixed);
        return resRa;
    }

    ///operator*
    template<typename NumT>
    template<typename ParamT, typename  std::enable_if <std::is_integral <ParamT> ::value, ParamT > ::type *>
    inline Rational<NumT> Rational<NumT>::operator*(const ParamT & rRational) const 
    {
        Rational<NumT> resRa(_numer * rRational, _denom);

        resRa.SetDenomFixed(m_isDenomFixed);
        return resRa;
    }

    template<typename NumT>
    template<typename ParamT, typename  std::enable_if <std::is_floating_point <ParamT> ::value, ParamT > ::type *>
    inline Rational<NumT> Rational<NumT>::operator*(const ParamT & rRational) const
    {
        Rational<int64_t> rightVal;
        FloatingToRational(rRational, rightVal);

        return *this * rightVal;
    }

    template<typename NumT>
    inline Rational<NumT> Rational<NumT>::operator*(const Rational & rRational) const
    {
        Rational<NumT> resRa;
        resRa(rRational._numer * _numer, rRational._denom * _denom);

        resRa.SetDenomFixed(m_isDenomFixed);
        return resRa;
    }

    ///operator /
    template<typename NumT>
    template<typename ParamT, typename  std::enable_if <std::is_integral <ParamT> ::value, ParamT > ::type *>
    inline Rational<NumT> Rational<NumT>::operator/(const ParamT & rRational) const
    {
        Rational<NumT> resRa;
        if (_numer % rRational == 0)
        {
            resRa(_numer / rRational, _denom);
        }
        else
        {
            resRa(_numer, _denom * rRational);
        }

        resRa.SetDenomFixed(m_isDenomFixed);
        return resRa;
    }

    template<typename NumT>
    template<typename ParamT, typename  std::enable_if <std::is_floating_point <ParamT> ::value, ParamT > ::type *>
    inline Rational<NumT> Rational<NumT>::operator/(const ParamT & rRational) const
    {
        Rational<int64_t> rightVal;
        Rational<NumT> resRa;
        FloatingToRational(rRational, rightVal);

        resRa(*this / rightVal);
        return resRa;
    }

    template<typename NumT>
    inline Rational<NumT> Rational<NumT>::operator/(const Rational & rRational) const
    {
        Rational<NumT> resRa;
        resRa(_numer * rRational._denom, _denom * rRational._numer);

        resRa.SetDenomFixed(m_isDenomFixed);
        return resRa;
    }

    ///operator =
    template<typename NumT>
    template<typename ParamT, typename  std::enable_if < std::is_integral <ParamT> ::value, ParamT > ::type *>
    inline Rational<NumT> Rational<NumT>::operator=(const ParamT & rRational)
    {
        Rational<NumT> resRa(_numer = rRational * _denom, _denom);
        
        resRa.SetDenomFixed(m_isDenomFixed);
        return resRa;
    }

    template<typename NumT>
    template<typename ParamT, typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type *>
    inline Rational<NumT> Rational<NumT>::operator=(const ParamT & rRational)
    {
        Rational<NumT> rightVal;
        Rational<NumT> resRa;

        FloatingToRational(rRational, rightVal);

        resRa(rightVal);
        (*this)(rightVal);

        return resRa;
    }

    template<typename NumT>
    inline Rational<NumT> Rational<NumT>::operator=(const Rational & rRational)
    {
        Rational<NumT> resRa;

        resRa(rRational);
        (*this)(rRational);
        return resRa;
    }

    ///operator ==
    template<typename NumT>
    template<typename ParamT, 
        typename  std::enable_if <
            std::is_integral <ParamT> ::value ||
                std::is_base_of<__Rational, ParamT>::value,
        ParamT> ::type *>
    inline bool Rational<NumT>::operator==(const ParamT & rRational) const
    {
        return (*this - rRational)._numer == 0;
    }

    template<typename NumT>
    template<typename ParamT, typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type *>
    inline bool Rational<NumT>::operator==(const ParamT & rRational) const
    {
        return IsEqualFloating(1.0 * _numer / _denom, rRational);
    }

    ///operator ()
    //Base Initialization  function.
    template<typename NumT>
    inline void Rational<NumT>::operator()(const NumT& newNumer, const NumT& newDenmo)
    {
        static_assert(std::is_integral<NumT>::value, "[Error] Error Number Type, Must be an integer.");

        _denom = newDenmo;
        _numer = newNumer;
    }

    //Base Initialization  function.
    template<typename NumT>
    inline void Rational<NumT>::operator()(const Rational & newRa)
    {
        (*this)(newRa._numer, newRa._denom);
        SetDenomFixed(newRa.GetDenomFixed());
    }

    ///
    template<typename NumT>
    template<typename ParamT,
        typename  std::enable_if <
            std::is_integral <ParamT> ::value ||
                std::is_floating_point <ParamT> ::value ||
                std::is_base_of<__Rational, ParamT>::value,
            ParamT> ::type *>
    inline bool Rational<NumT>::operator!=(const ParamT & rRational) const
    {
        return !(*this == rRational);
    }

    template<typename NumT>
    template<typename ParamT,
        typename  std::enable_if <
            std::is_integral <ParamT> ::value ||
                std::is_floating_point <ParamT> ::value ||
                std::is_base_of<__Rational, ParamT>::value,
        ParamT> ::type *>
    inline bool Rational<NumT>::operator>(const ParamT & rRational) const
    {
        return (*this - rRational)._numer > 0;
    }

    ////operator < >= <=
    template<typename NumT>
    template<typename ParamT,
        typename  std::enable_if <
            std::is_integral <ParamT> ::value ||
                std::is_floating_point <ParamT> ::value ||
                std::is_base_of<__Rational, ParamT>::value,
        ParamT> ::type *>
    inline bool Rational<NumT>::operator<(const ParamT & rRational) const 
    {
        return (*this - rRational)._numer < 0;
    }

    template<typename NumT>
    template<typename ParamT,
        typename  std::enable_if <
            std::is_integral <ParamT> ::value ||
                std::is_floating_point <ParamT> ::value ||
                std::is_base_of<__Rational, ParamT>::value,
            ParamT
        > ::type *>
    inline bool Rational<NumT>::operator>=(const ParamT & rRational)
    {
        return !(*this < rRational);
    }

    template<typename NumT>
    template<typename ParamT, 
        typename  std::enable_if <
            std::is_integral <ParamT> ::value ||
                std::is_floating_point <ParamT> ::value ||
                std::is_base_of<__Rational, ParamT>::value,
        ParamT> ::type * >
    inline bool Rational<NumT>::operator<=(const ParamT & rRational)
    {
        return !(*this > rRational);
    }

    template<typename NumT>
    template<typename ParamT,
        typename  std::enable_if <
            std::is_integral <ParamT> ::value ||
                std::is_floating_point <ParamT> ::value ||
                std::is_base_of<__Rational, ParamT>::value,
        ParamT> ::type * >
    inline Rational<NumT> Rational<NumT>::operator+=(const ParamT & rRational)
    {
        return *(this) = *(this) + rRational;
    }

    template<typename NumT>
    template<typename ParamT,
        typename  std::enable_if <
        std::is_integral <ParamT> ::value ||
        std::is_floating_point <ParamT> ::value ||
        std::is_base_of<__Rational, ParamT>::value,
        ParamT> ::type * >
        inline Rational<NumT> Rational<NumT>::operator-=(const ParamT & rRational)
    {
        return *(this) = *(this) - rRational;
    }

    template<typename NumT>
    template<typename ParamT,
        typename  std::enable_if <
        std::is_integral <ParamT> ::value ||
        std::is_floating_point <ParamT> ::value ||
        std::is_base_of<__Rational, ParamT>::value,
        ParamT> ::type * >
        inline Rational<NumT> Rational<NumT>::operator*=(const ParamT & rRational)
    {
        return *(this) = *(this) * rRational;
    }

    template<typename NumT>
    template<typename ParamT,
        typename  std::enable_if <
        std::is_integral <ParamT> ::value ||
        std::is_floating_point <ParamT> ::value ||
        std::is_base_of<__Rational, ParamT>::value,
        ParamT> ::type * >
        inline Rational<NumT> Rational<NumT>::operator/=(const ParamT & rRational)
    {
        return *(this) = *(this) / rRational;
    }

    template<typename NumT>
    template<typename ParamT,
        typename  std::enable_if <
                std::is_floating_point <ParamT> ::value,
        ParamT> ::type *>
    inline Rational<NumT>::operator ParamT()
    {
        return static_cast<ParamT>((_numer * 1.0) / _denom);
    }

    template<typename NumT>
    template<typename ParamT,
        typename  std::enable_if <
            std::is_integral <ParamT> ::value,
        ParamT> ::type *>
    inline Rational<NumT>::operator ParamT()
    {
        return  _numer / _denom;
    }

    template<typename NumT>
    template<typename ParamT, typename  std::enable_if < std::is_floating_point <ParamT> ::value, ParamT > ::type *>
    inline void Rational<NumT>::FloatingToRational(const ParamT & num, Rational<NumT>& res)
    {
        static const long double BaseDenmo = 1e12;
        Rational<int64_t> tempRes;
        tempRes.SetDenomFixed(res.GetDenomFixed());

        tempRes(static_cast<int64_t>(num * BaseDenmo), static_cast<int64_t>(BaseDenmo));
        tempRes.DenomFix(true);

        res(tempRes);
    }

    //////////////////////////////////////////////////////////////////////////////////
};



    //////////////////////////////////////////////////////////////////////////////////
};

main.cpp 测试主函数


#include "Tilee.h"
#include "Location.h"
#include "stdinc.h"
#include "Random.h"
#include "Rational.h"

using namespace Lunacia;

//struct Item 
//{
//  uint32_t weight;
//  int id;
//};

int main(void)
{

    int a = 12;
    int b = 9;

    int64_t lcm = Rational<int64_t>::Lcm(a, b);
    std::cout << lcm << std::endl;
    
    Rational<int64_t> rnum(2, 4, true);
    Rational<int32_t> rnum2(5, 8, false);

    std::string aaa;
    rnum.GetRationalString(aaa);
    std::cout << aaa << std::endl;

    double da = 0.24;
    double dda = 0.24*std::pow(10, 12);
    //rnum(rnum2);

    int iA = 2;
    long long iB = 3;
    rnum(iA, iB);

    Rational<int64_t> ra1 = rnum + iB;
    rnum + 2.6;
    rnum + rnum2;

    Rational<int32_t> ra2 = rnum - 5;
    rnum - 0.25;
    rnum - rnum2;

    Rational<int> ra3 = rnum * 3;
    rnum * 1.5;
    rnum * rnum2;

    ra3 = rnum / 4;
    Rational ra4 = rnum / 2.50;
    rnum / rnum2;

    bool isEqual = rnum == rnum2;
    rnum != rnum2;
    rnum > rnum2;
    rnum >= rnum2;
    rnum < rnum2;
    rnum <= rnum2;

    rnum == 5;
    rnum != 5;
    rnum > 5;
    rnum >= 5;
    rnum < 5;
    rnum <= 5;

    long double ldaa = 0.5;
    rnum == 1.5;
    rnum != 3.5;
    rnum > 2.5;
    rnum >= 4.5f;
    rnum < 6.5;
    rnum <= ldaa;

    rnum(rnum2);
    system("pause");
    return 0;
}

呵呵呵呵呵,好无聊。

猜你喜欢

转载自www.cnblogs.com/rkexy/p/9768519.html
今日推荐