计算幅度 <1 和幅度 >1 时的精度损失

Accuracy loss when calculating magnitudes <1 with magnitudes >1

本文关键字:损失 精度 lt 计算 gt      更新时间:2023-10-16

我正在测试字符串构建的gmp_float

这段代码

#include <boost/multiprecision/number.hpp>
#include <boost/multiprecision/gmp.hpp>
#include <iostream>
using namespace boost::multiprecision;
typedef number<gmp_float<15>> mp_type;
int main()
{
    mp_type total("1.01");
    cout << total.str(0) << endl;
    mp_type first_addition(".01");
    cout << first_addition.str(0) << endl;
    total += first_addition;
    cout << total.str(0) << endl;
}

打印

1.01
0.01
1.01999999999999999998

为什么?我进行了更多的测试,在这种特殊情况下,只要一个数字的大小>0和<1,而另一个数字的大小>1,那么操作是什么并不重要。

从上面的链接

不可能将此类型的对象往返于字符串并返回完全相同的值。这似乎是GMP的限制。

是否有其他区域会失去准确性?

Boost Multiprecision也支持十进制浮点数:

查看Live On Coliru prints:

clang++ -std=c++11 -Os -Wall -pedantic main.cpp && ./a.out
1.01
0.01
1.02

#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
using namespace boost::multiprecision;
using std::cout;
using std::endl;
typedef cpp_dec_float_50 mp_type;
int main()
{
    mp_type total("1.01");
    cout << total.str(0)          << endl;
    mp_type first_addition(".01");
    cout << first_addition.str(0) << endl;
    total += first_addition;
    cout << total.str(0)          << endl;
}

mpf_t在GMP中是一个二进制浮点数。0.01不能精确地表示为任何有限精度的二进制浮点数。

0.01更改为0.125,将1.01更改为1.125,使格式化的输出看起来很好。这是因为0.1251.125可以精确地表示为至少8位有效位的二进制浮点数。