在C++中,float占4个字节,double占8个字节,均采用 IEEE 754 浮点标准;内部都是以二进制为基础,表述实数,有些实数能够被精确表述,好比0.2,但有些不行,好比0.3。针对这一点,前不久有篇专门的文章介绍这个:浮点运算为何不许?有人为0.30000000000000004建了个网站ios
为了可以表述更高精度的浮点数,就得向库方向查找了。gmp, mpfr 能够表述无限精度,但编译只能gcc吧,boost在1.56版时开始提供 boost.multiprecision 用于支持更高精度数值表述,许可证较其余库宽松,但在计算效率等方向要逊于gmp, mpfr。c++
好比采用 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次结果以下:
3d
明显使用double计算时,第10次以后就每没有什么变化了(小于2.2204460492503131e-016 (即DBL_EPSILON)的值与 1.0 相加仍然为1.0),而boost.multiprecision还一直在变化,而且结果能够与Window操做系统中计算器存储的pi值相同(但小数点以后更多数字,这些准不许确就没比较了)。code