65.9K
CodeProject 正在变化。 阅读更多。
Home

Boost 多精度库

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (19投票s)

2016年4月12日

CPOL

2分钟阅读

viewsIcon

53983

downloadIcon

659

Boost 多精度库简介。

引言

Boost 库在当前的 1.53.0 版本中包含了一个新的 多精度库。对于需要超过 64 位精度的 C++ 程序员来说,这个库无疑会很有用。注意:我与 Boost 或该库没有任何关联。

128 位整数示例

下面的代码展示了使用 128 位整数来计算 21 的阶乘。该库开箱即用支持高达 1024 位的精度。如果需要,用户可以定义更高的精度。

#include <intrin.h>
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
#include <iomanip>

using boost::multiprecision::int128_t;
using namespace std;

int128_t Factorial(int num);

void main()
{
    cout << Factorial(21) << endl;
}

int128_t Factorial(int num)
{
    int128_t fact = 1;
    for(int i=num; i>1; --i)
    {
        fact *= i;
    }

    return fact;
}
This is the output:
51090942171709440000

任意精度整数示例

库中还包含一个任意精度整数,cpp_int。下面的示例使用任意精度整数来计算 21 的阶乘。请注意,代码与上面的代码几乎相同。

#include <intrin.h>
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
#include <iomanip>

using boost::multiprecision::cpp_int;
using namespace std;

cpp_int Factorial(int num);

void main()
{
    cout<< Factorial(21) << endl;
}

cpp_int Factorial(int num)
{
    cpp_int fact = 1;
    for(int i=num; i>1; --i)
    {
        fact *= i;
    }

    return fact;
}
This is the output:
51090942171709440000

该库为后端提供了封装,例如 GNU 多精度算术库TomMath,但需要用户自行下载和构建相应的库。Boost 自带版本的性能通常优于 TomMath,并且与 GMP 相当或稍慢。使用这些后端封装的优势在于,学习第三方库的学习曲线大大降低。

随机数生成

用户可以使用 Mersenne Twister 19937 生成器生成一些随机的 128 位整数。

#include <intrin.h>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/random.hpp>
#include <iostream>
#include <iomanip>
#include <boost/chrono/chrono.hpp>

using namespace boost::multiprecision;
using namespace boost::random;

void main()
{
    //
    // Generate integers in a given range using cpp_int,
    // the underlying generator is invoked multiple times
    // to generate enough bits:
    //
    mt19937 mt;
    mt.seed(boost::chrono::system_clock::to_time_t(boost::chrono::system_clock::now()));
    uniform_int_distribution<cpp_int> ui(0, cpp_int(1) << 128);
    //
    // Generate the numbers:
    //
    std::cout << std::hex << std::showbase;
    for(unsigned i = 0; i < 10; ++i)
        std::cout << ui(mt) << std::endl;
	
}
This is the output:
0xD5C31F79E7E1FAEE22AE9EF6D091BB5C
0xA1E24BBA3895AFE1E9D30005F807B7DF
0xCCDF2E5CCC50AA597C4194181C1FE652
0xADC1965BAE6D9426EF1A2E6D3640AC4C
0x7989C8EEBE3DEDFCBD9B0ECDC1FB41C2
0x2BD2E4122C826D8BA7CD66346C0DF032
0x5109733008263282CC1A8959B4BF6FA7
0x200BFA47B1E049E1D268409AD2CE21C9
0x2FD6E208095436BFCB92388E0D1C8509
0x1E76A1C5A4DAA01029A0EC27B5F0B06C

多精度浮点数

对于浮点类型,用户可以使用 cpp_dec_float_50cpp_dec_float_100 获得高达 50 或 100 位小数的精度。下面的代码来自 Boost 圆面积示例

#include <boost/math/constants/constants.hpp>

template<typename T>
inline T area_of_a_circle(T r)
{
   using boost::math::constants::pi;
   return pi<T>() * r * r;
}
#include <iostream>
#include <iomanip>
#include <boost/multiprecision/cpp_dec_float.hpp>

using boost::multiprecision::cpp_dec_float_50;

void main()
{
   const float r_f(float(123) / 100);
   const float a_f = area_of_a_circle(r_f);

   const double r_d(double(123) / 100);
   const double a_d = area_of_a_circle(r_d);

   const cpp_dec_float_50 r_mp(cpp_dec_float_50(123) / 100);
   const cpp_dec_float_50 a_mp = area_of_a_circle(r_mp);

   // 4.75292
   std::cout
      << std::setprecision(std::numeric_limits<float>::digits10)
      << a_f
      << std::endl;

   // 4.752915525616
   std::cout
      << std::setprecision(std::numeric_limits<double>::digits10)
      << a_d
      << std::endl;

   // 4.7529155256159981904701331745635599135018975843146
   std::cout
      << std::setprecision(std::numeric_limits<cpp_dec_float_50>::digits10)
      << a_mp
      << std::endl;
} 

支持多精度浮点数的常见三角函数,例如 sincostanasinacosatan。用户还可以计算对数和平方根。有关更多信息,请查看 default_ops.hpp

本文只是触及了多精度库的表面。请访问 Boost 多精度库页面以了解更多信息。

关注点

我在寻找一个好的任意精度整数库来用于我的下一篇组合数学文章时,偶然发现了这个 Boost 库。对于我的文章来说,速度不是问题,因为我的阶乘是预先计算的。感谢您的阅读!

© . All rights reserved.