不想写高精度,就用boost

· · 个人记录

第二次推广boost了。

boost是什么?

Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称。

安装及使用见 感受C++那神奇的boost。

整数

参见官方说明。

boostcpp_inttom_intgmp_int为高精整数类型。

这里着重介绍cpp_int(因为我感觉几个类型用法几乎一模一样),其他参见官方说明。

对比

名称 头文件 基数 依存关系 优点 缺点
cpp_int boost / multiprecision / cpp_int.hpp 2 没有 非常通用的,Boost授权的,所有C ++整数类型,支持任意精度和固定精度整数类型。 比GMP慢,尽管通常不如libtommath慢
gmp_int boost / multiprecision / gmp.hpp 2 GMP 非常快速高效的后端。 对GNU许可的GMP库的依赖。
tom_int boost / multiprecision / tommath.hpp 2 libtommath 公共域后端,无许可证限制。 比GMP慢。

cpp_int

所用库与命名空间如下:

#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;

基本运算 输入输出

+-*/cincout等与其他类型相同:

#include<iostream>
using namespace std;
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;

int main()
{
    cpp_int a,b; 
    cin>>a>>b;
    cout<<"a+b="<<a+b<<endl;
    cout<<"a-b="<<a+b<<endl;
    cout<<"a*b="<<a*b<<endl;
    cout<<"a/b="<<a/b<<endl;//除法与普通整数类型一样,向下取整
    cout<<"a%b="<<a%b<<endl;
    return 0;
}

效果(交的时候手误*写成了+,懒得改了):

实例 计算阶乘

#include <iostream>
using namespace std;
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
int main()
{
    cpp_int v = 1;
    for(unsigned i = 1; i <= 20; ++i)
        v *= i;
    cout<<"20!="<<v<<endl;

    cpp_int u = 1;
    for(unsigned i = 1; i <= 100; ++i)
        u *= i;
    cout<<"100!="<<u<<endl;
    return 0;
}

效果:

(可谓打表神器啊~)

浮点数

参见官方说明。

boost中浮点数有cpp_dec_floatmpfr_floatcpp_bin_floatfloat128gmp_float

这里着重介绍cpp_dec_float(原因同上),其他参见官方说明。

对比

名称 头文件 基数 依存关系 优点 缺点
cpp_bin_float boost / multiprecision / cpp_bin_float.hpp 2 仅需头文件 比MPFR 或GMP库慢大约2倍
cpp_dec_float boost / multiprecision / cpp_dec_float.hpp 10 仅需头文件 比MPFR 或GMP库慢大约2倍
mpf_float boost / multiprecision / gmp.hpp 2 GMP 非常快速高效的后端 对GNU许可的GMP库的依赖
mpfr_float boost / multiprecision / mpfr.hpp 2 GMP和MPFR 具有自己的标准库实现的非常快速和高效的后端 对GNU许可的GMP 和MPFR库的依赖
float128 boost / multiprecision / float128.hpp 2 libquadmath 或Inter C ++数学库。 非常快速和高效的后端,用于128位浮点值 取决于编译器是最新的GCC还是Intel C ++版本

cpp_dec_float

boostcpp_dec_floatcpp_dec_floatcpp_dec_float_50cpp_dec_float_100

使用库与命名空间如下:

#include <boost/multiprecision/cpp_dec_float.hpp>
using namespace boost::multiprecision;

这三个有什么区别?

答:精度不同, cpp_dec_float_50 和cpp_dec_float_100提供分别为50和100个十进制数字精度的算术类型。

就用cpp_dec_float_100吧,比较省心。

+-*/cincout等也与其他类型相同:

可以使用setprecision(std::numeric_limits<cpp_dec_float_100>::max_digits10)显示所有位数。

#include<iostream>
using namespace std;
#include <boost/multiprecision/cpp_dec_float.hpp>
using namespace boost::multiprecision;

int main()
{
    cpp_dec_float_100 a,b;
    cin>>a>>b;
    cout<< "a="<<a<<endl;
    cout<< "b="<<b<<endl;
    cout<< "a+b="<<a+b<<endl;
    cout<< "a-b="<<a-b<<endl;
    cout<< "a*b="<<a*b<<endl;
    return 0;
}

效果:

小实例

#include <iostream>
using namespace std;
#include <boost/multiprecision/cpp_dec_float.hpp>
using namespace boost::multiprecision;
#include <boost/math/special_functions/gamma.hpp>
using namespace boost::math;

int main()
{
    cpp_dec_float_100 b=2;
    cout<<numeric_limits<cpp_dec_float_100>::digits<<endl;
    //注意,由于我们以10为底,所以digits10与digits相同!:
    cout<<numeric_limits<cpp_dec_float_100>::digits10<<endl;
    //我们可以使用任何C ++ std lib函数,也可以打印所有数字:
    cout<<setprecision(std::numeric_limits<cpp_dec_float_100>::max_digits10)<<log(b)<<endl; 
    //我们也可以使用Boost.Math中的任何函数:
    cout<<tgamma(b)<<endl;
    //当参数是表达式模板时,它们甚至也可以工作:
    cout<<tgamma(b*b)<<endl;
    //既然我们有较长的指数范围,我们可以产生一些真正的大数
    //这里的数字(4.0238726007709377354370243e + 2564):
    cout<<tgamma(cpp_dec_float_100(1000))<<endl;
    return 0;
}

效果:

实例 莱布尼茨公式计算\pi

\dfrac{\pi}{4}=\dfrac{1}{1}-\dfrac{1}{3}+\dfrac{1}{5}-\dfrac{1}{7}+...... \pi=\dfrac{4}{1}-\dfrac{4}{3}+\dfrac{4}{5}-\dfrac{4}{7}+......
#include <iostream>
using namespace std;
#include <boost/multiprecision/cpp_dec_float.hpp>
using namespace boost::multiprecision;

int main()
{
    cpp_dec_float_100 ans=0.0,i=1.0;
    int h=1;
    while(1)
    {
        ans+=cpp_dec_float_100(h*4.0/i);
        i+=2,h=-h;
        cout<<setprecision(std::numeric_limits<cpp_dec_float_100>::max_digits10)<<ans<<endl;
    }
    return 0;
}

效果:

结束了?

本文只介绍部分典型的函数及功能,毕竟600多mb的东西谁一次讲得完。

本文所涉及到的只是boost中很小的一部分,但足以看出boost的强大!

boost的范围极广,可以说是加强版的STL,非常值得深入学习理解。

boost常用库

Regex

正则表达式库

Spirit

LL parser framework,用C++代码直接表达EBNF

Graph

图组件和算法

Lambda

在调用的地方定义短小匿名的函数对象,很实用的functional功能

concept check

检查泛型编程中的concept

Mpl

用模板实现的元编程框架

Thread

可移植的C++多线程库

Python

把C++类和函数映射到Python之中

Pool

内存池管理

smart_ptr

5个智能指针,学习智能指针必读

更多内容参见boost中文教程与boost官网(本文参考资料)。

如果哪天你谷支持了boost别忘了叫我啊。