不知道为什么,但是如果我将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-05
与0.01887054927647113800048828125
有人可以向我解释一个聪明的例子为什么会发生这种情况吗?
答案 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。
因此,当使用浮点数时,存在舍入误差,该舍入误差只是有效数字中最低有效数字的位置值的一部分。当数字具有更大的指数时,可能的误差会更大。误差始终在最低有效位的位置值的零到一半之间(因为两个可表示数字之间的任何数字都在中点或彼此接近,所以永远不必将数字移到一半以上)。可表示数字之间的距离。)
因此,当使用更大的数字时,舍入误差会更大。