为什么在浮点数中从大到小的引入更多错误?

时间:2018-11-04 11:00:45

标签: c++ floating-point rounding-error

不知道为什么,但是如果我将fp数字大一点,看来增量误差是bigger

#include <iostream>
#include <math.h>

int main() {
    std::cout.precision(50);

    const int numLoops = 1000;
    const long length = 10000;
    const double rate = 0.1;

    long totalLength = length * numLoops;
    long long steps = (long long)(totalLength / rate);

    double sum = 0.0;
    double sumRemainder = 0.0;
    for (long long step = 0; step < steps; step++) {
        if (sumRemainder >= length) {
            sumRemainder = fmod(sumRemainder, length);
        }

        sum += rate;
        sumRemainder += rate;
    }

    std::cout << "                  length: " << length << std::endl;
    std::cout << "               num loops: " << numLoops << std::endl;
    std::cout << "                    rate: " << rate << std::endl;
    std::cout << "                   steps: " << steps << std::endl << std::endl;
    std::cout << "                     sum: " << sum << std::endl;
    std::cout << "           sum remainder: " << sumRemainder << std::endl;
    std::cout << "                   error: " << abs(totalLength - sum) << std::endl;
    std::cout << "         error remainder: " << abs(length - sumRemainder) << std::endl;
    std::cout << std::endl;
}

这两个和之间的唯一区别是,一个是针对所有步骤的,而另一方面,我只是简单地将结果一达到极限就修改了fmod(因此,它将钳位到一个很小的值):

sumRemainder = fmod(sumRemainder, length);

这似乎是在加总相同数量的同时引入低错误的原因:1.884836819954216480255126953125e-050.01887054927647113800048828125

有人可以向我解释一个聪明的例子为什么会发生这种情况吗?

1 个答案:

答案 0 :(得分:2)

要处理大号或小号,浮点格式将缩放数字。固定数量的数字用于数字的有效位,并且它们由某个基数(通常为2)提升为幂,称为指数。还有一个符号,+或-,尽管符号有时包含在有效数字中。

例如,使用二进制格式,当指数为零时,1.011 2 的有效位数表示1 + 3/16(1.011 2 •2 0 = 1 + 3/16),以4的指数缩放时为11(1.011 2 •2 4 = 11),以及11/32当以-1的指数缩放时(1.011 2 •2 -1 = 11/32)。

有效位数有固定位数。因此只能表示某些数字。当执行任何算术运算时,精确的数学结果将四舍五入到最接近的可表示数字。 (通常的四舍五入默认规则是四舍五入到最接近的可表示值,如果有平局,则四舍五入,以使低位数字保持偶数。)

例如,对于十进制格式,其有效位数为三个十进制数字,请考虑将数字567(5.67•10 2 )和789(7.89•10 2 )。结果是1356,但是位数太多。因此,将其舍入为1360(1.36•10 3 )。舍入误差为4。

因此,当使用浮点数时,存在舍入误差,该舍入误差只是有效数字中最低有效数字的位置值的一部分。当数字具有更大的指数时,可能的误差会更大。误差始终在最低有效位的位置值的零到一半之间(因为两个可表示数字之间的任何数字都在中点或彼此接近,所以永远不必将数字移到一半以上)。可表示数字之间的距离。)

因此,当使用更大的数字时,舍入误差会更大。