在处理浮点数时避免不稳定的小数字

Avoiding erratic tiny numbers when working with floating point numbers

本文关键字:不稳定 小数 数字 处理 浮点数      更新时间:2023-10-16

有时候,当我在c++中使用浮点数时,只使用数字的倍数,比如0.1,作为for循环中的增量,循环迭代器的实际数字并不完全是0.1的倍数,而是不可预测地添加或减去1^-17数量级的微小数字。我怎样才能避免呢?

使用整数进行迭代,并在使用前乘以浮点数自增。

或者找到一个十进制数学包并使用它来代替浮点数。

不要迭代浮点数

问题是0.1不能精确地用浮点数表示。所以,你应该这样做:

for (int i = 0; i < N; i++)
{
    float f = i * 0.1f;
    ...
}

这是一篇关于如何使用浮点数的优秀文章。有一个讨论正好涵盖了您的示例—0.1的增量:

for (double r=0.0; r!=1.0; r+=0.1) printf("*");

它要打印多少颗星星?十个?运行它并获得惊喜。代码会一直输出星号,直到我们打破它。

有什么问题吗?正如我们已经知道的,双精度不是无限精确的。我们在这里遇到的问题如下:在二进制中,0.1的表示不是有限的(因为它是以10为基数的)。十进制0.1相当于二进制0.0(0011),其中括号中的部分永远重复。当0.1存储在双变量中时,它将四舍五入到最接近的可表示值。因此,如果我们把它加10次,结果并不完全等于1。

如果你经常使用浮点数,我强烈建议你阅读整篇文章。