码迷,mamicode.com
首页 > 其他好文 > 详细

浮点运算与boost.multiprecision

时间:2019-12-06 18:53:06      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:标准   网站   许可证   这一   精确   ++   ret   static   eps   

在C++中,float占4个字节,double占8个字节,均采用 IEEE 754 浮点标准;内部都是以二进制为基础,表述实数,有些实数可以被精确表述,比如0.2,但有些不行,比如0.3。针对这一点,前不久有篇专门的文章介绍这个:浮点运算为什么不准?有人为0.30000000000000004建了个网站

为了能够表述更高精度的浮点数,就得向库方向查找了。gmp, mpfr 可以表述无限精度,但编译只能gcc吧,boost在1.56版时开始提供 boost.multiprecision 用于支持更高精度数值表述,许可证较其他库宽松,但在计算效率等方向要逊于gmp, mpfr。

比如采用 bbp 公式计算 pi 的精确结果,代码如下:

// Author: bitbybit3d@163.com

#include <iostream>
#include <iomanip>
#include <boost/math/constants/constants.hpp>
#include <boost/multiprecision/cpp_bin_float.hpp>

// 通过 BBP 公式计算 PI
template <class Type>
Type calc_pi_bbp(int n)
{
    Type pi = 0;

    std::streamsize prevsize = std::cout.precision(50);
    for (int k = 0; k < n; ++k)
    {
        Type it = static_cast<Type>(1) / pow(16, k)
            * (static_cast<Type>(4) / (8 * k + 1) 
                - static_cast<Type>(2) / (8 * k + 4)
                - static_cast<Type>(1) / (8 * k + 5)
                - static_cast<Type>(1) / (8 * k + 6));
        pi += it;
        std::cout << std::left << std::setw(8) << k << pi << std::endl;
    }
    std::cout.precision(prevsize);
    return pi;
}

int main(int argc, char* argv[])
{
    std::cout << "Use double: " << std::endl;
    calc_pi_bbp<double>(20);
    std::cout << std::endl;

    std::cout << "Use boost multiprecision: " << std::endl;
    calc_pi_bbp<boost::multiprecision::cpp_bin_float_100>(30);
    return 0;
}

以double值计算20次结果如下:
技术图片

再以boost.multiprecision计算30次结果如下:
技术图片

明显使用double计算时,第10次之后就每没有什么变化了(小于2.2204460492503131e-016 (即DBL_EPSILON)的值与 1.0 相加仍然为1.0),而boost.multiprecision还一直在变化,并且结果可以与Window操作系统中计算器存储的pi值相同(但小数点之后更多数字,这些准不准确就没比较了)。

浮点运算与boost.multiprecision

标签:标准   网站   许可证   这一   精确   ++   ret   static   eps   

原文地址:https://www.cnblogs.com/bitbybit3d/p/11995816.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!