boost rational有理数 tcy

1.1.下载 boost 库地址:https://www.boost.org/  压缩文件boost_1_75_0.7z
       或下载boost_1_75_0-msvc-14.1-64.exe  https://sourceforge.net/projects/boost/files/boost-binaries/1.75.0/
1.2.说明:
	大多数的 boost 库仅需要包含头文件 hpp 即可,不需要再链接其他的 lib 文件,
	但是有些 boost 下的库是需要包含 lib 文件的	   

1.2.我下载的是第一个,有理数库不需要编译只做简单路径设置
      将 boost 库的路径添加到附加包含目录查看:https://blog.csdn.net/weixin_38102771/article/details/88410617
       VS2019 prew我的设置:
	   C/C++-->包含目录:C:\boost_1_75_0;(首先你应解压拷贝到C:\)
	   链接器-->附加库目录:C:\boost_1_75_0\libs;

2.实例

#include <boost\rational.hpp>
#include <iostream>

using namespace std;
using namespace boost;

template <typename T>
bool isOdd(T value) { return (value & 1) == 1; }

template <typename T>
bool isEven(T value) { return (value & 1) == 0; }
template <typename T>
int sgn(T value) {
    if (value == 0) return 0;
    else if (value > 0) return 1;
    else
        return -1;
}
template<typename T>
bool isIntFlower(T value, T now) {
    return sgn(value)!=sgn(now);
}
template<typename T>
rational<T> swapNumeratorDenominator(const rational<T>& v) {
    return rational<T>(v.denominator(),v.numerator());
}

实现自定义有理数Power函数

要求有理数数据类型为整数类型。 

template<typename T>
rational<T> Power(const rational<T>& base, int exponent) {
    int exp = exponent;
    rational<T> result(0);
    if (result == base)return result;
    if (exp == 0)return rational<T>(1);

    if (exp>0)
        result = base;
    else
    {
        result = swapNumeratorDenominator(base);
        exp = abs(exp);
    }

    if (base < 0 && isEven(exp))
       result = abs(base);
      
    //开始计算
    T numerator= result.numerator();     //分子
    T denominator = result.denominator();//分母

    T old_num = numerator;
    T old_deno = denominator;

    T res1 = 1,res2=1;
    while (exp != 0)
    {
        if ((exp & 1) == 1)
        {
            res1 *= numerator;
            res2 *= denominator;
        }

        numerator *= numerator;        // 翻倍
        denominator *= denominator;    // 翻倍
        exp >>= 1;                     // 右移一位

        if (isIntFlower(old_num, res1) || isIntFlower(old_deno, res2))
            throw "int flower!";   
    }
    result = { res1,res2 };

    return result;
}
void test_Power() {
   
    cout << "10^4=" << Power<long long>(10, 4) << endl;//=10000 / 1
    cout << "10^-4=" << Power<long long>(10, -4) << endl;//= 1 / 10000
    cout << "(-10)^-4=" << Power<long long>(-10, 4) << endl;//= 10000 / 1
    cout << "(-10)^-4=" << Power<long long>(-10, -4) << endl;//= 10000 / 1
    cout << "(3/2)^2=" << Power<long long>(rational<long long>(3, 2), 2) << endl;//= 9 / 4
    cout << "(-3/2)^-2=" << Power<long long>(rational<long long>(3, 2), -2) << endl;// = 4 / 9
    cout << "(3/-2)^2=" << Power<long long>(rational<long long>(-3, 2), 2) << endl;//= 9 / 4
    cout << "(3/2)^2=" << Power<long long>(rational<long long>(3, -2), 2) << endl;//= 9 / 4
    cout << "(3/-2)^0=" << Power<long long>(rational<long long>(3, -2), 0) << endl;//= 1 / 1
}
void test_rational() {
    using std::cout;

    //创建有理数
    rational<int> a1(0);                          //=0/1

    // 输出一个既约分数的形式
    cout << "4/2=" << rational<int>(4, 2) << endl;//=2/1

    cout << "分子=" << a1.numerator() << endl;    //分子=0
    cout << "分母=" << a1.denominator() << endl; //分母=1

    //修改值:
    a1 = { 2,4 };    //1/2
    a1 = 10;           //=10/1
    a1.assign(3, 5); //=3/5

    //四则运算:
    const rational<int> x1{ rational<int>(-3, 2) };
    const rational<int> x2 = rational<int>(4, 2);

    cout << "x1+x2=" << x1 + x2 << endl;//=7/2
    cout << "x1-x2=" << x1 - x2 << endl;//-1/2
    cout << "x1*x2=" << x1 * x2 << endl;//=3/1
    cout << "x1/x2=" << x1 / x2 << endl;//=3/4

    cout << "|x1|=" << abs(x1) << std::endl;

    //转浮点数:
    cout << "double=" << rational_cast<double>(x1) << endl;

    cout << "最大公约数=" << gcd(x1, x2) << endl;//=1/2
    cout << "最小公倍数" << lcm(x1, x2) << endl; //=6/1

    //需要转化为double才可以用于pow/cos/sqrt等
    cout << pow(rational_cast<double>(x2), 2) << endl;
    cout << sqrt(rational_cast<double>(x2)) << endl;
    cout << cos(rational_cast<double>(x2)) << endl;

    //测试异常:
    rational<int64_t> b(1, 2);

    try {
        cout << b << endl;
        cout << "b/0=" << b / 0 << endl;
    }
    catch (bad_rational& e) {
        cout << e.what() << endl;//b/0=bad rational: zero denominator
    }
}
int main() {
    test_Power();
    test_rational();
}

 3.备注:Power实现原理

参考https://blog.csdn.net/qq_41822235/article/details/81777291非递归版本

1.全面考察指数的正负、底数是否为零等情况。
2.写出指数的二进制表达,例如13表达为二进制1101。
3.举例:10^1101 = 10^0001*10^0*10^0100*10^1000。
4.通过&1和>>1来逐位读取1101,为1时将该位代表的乘数累乘到最终结果。

 实例:

double Power(double base, int exponent) {
       
        bool isPositiveNum = true;
        double res = 1;
        if(exponent > 0);
        else if(exponent < 0)
        {
            isPositiveNum = false;
            if(base==0)
                return 0;
            exponent = -exponent;    //变成正数
        }
        else
        {
            if(base==0)
                return 0;
            return 1;
        }
 
        while(exponent!=0)
        {
            if((exponent&1)==1)
                res*=base;
          
            base*=base;    // 翻倍
            exponent>>=1;// 右移一位
        }
 
        return isPositiveNum == true ? res:(1 / res);   
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值