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

Posted

技术标签:

【中文标题】计算幅度<1且幅度>1时的精度损失【英文标题】:Accuracy loss when calculating magnitudes <1 with magnitudes >1 【发布时间】:2014-05-31 00:37:17 【问题描述】:

我正在测试构造 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,那么操作是什么并不重要。

从上面的链接

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

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

【问题讨论】:

即使gmp_float 被宣传为具有“更高的精度”,我怀疑精度是无限的。尤其是在0附近。 Here我已经为那些感兴趣的人复制了这个问题。 离 [0.0,1.0] 越远,浮点数越容易受到精度问题的影响。如果您希望在可表示的整个值范围内具有相同的精度,请改用定点。顺便说一句,您甚至不能将 0.01 表示为浮点中的二次幂。 【参考方案1】:

Boost Multiprecision 也有十进制浮点数:

查看 Live On Coliru 打印:

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;

【讨论】:

【参考方案2】: GMP 中的

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

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

【讨论】:

我相信gmp_float 只是包装mpf_t。我使用的mpf_class 只是包装了mpf_t @Gracchus:为什么?你为什么关心十的幂? @Gracchus:恶心。用美分或任何被测量的最小货币单位来衡量一切。或者如果你真的需要的话,可以使用一些十进制浮点数。如果您选择理解二进制浮点,它仍然是您的朋友。 @Gracchus:存在十进制浮点格式和库。我不认为 gmp 有一个。我没有使用它们的经验,所以我不能推荐使用哪个。 +1 提供信息,我已经用适当的提升解决方案回答了

以上是关于计算幅度<1且幅度>1时的精度损失的主要内容,如果未能解决你的问题,请参考以下文章

什么是惩罚幅度和符号差异的良好损失函数

logistic / sigmoid函数实现数值精度

苹果加速框架——约束幅度而不损失绝对值

为高精度计算损失函数的权重

如何提高机器学习的分类精度

传递变量作为函数参数时由于隐式铸造导致的精度损失