mar*_*zzz -1 c++ floating-point rounding-error
不知道为什么,但如果我将大到小的 fp 数字相加,似乎增量误差会更大:
#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;
}
Run Code Online (Sandbox Code Playgroud)
两个总和之间的唯一区别是,一个适用于所有步骤,而另一个我只是在达到极限后对结果进行 fmod(因此,它会限制为一个小值):
sumRemainder = fmod(sumRemainder, length);
Run Code Online (Sandbox Code Playgroud)
看来这就是它在求和相同数量时引入低误差的原因:1.884836819954216480255126953125e-05与0.01887054927647113800048828125
有人可以用一个聪明的例子向我解释为什么会发生这种情况吗?
为了处理大数或小数,浮点格式会对数字进行缩放。数字的有效数使用固定数量的数字,并且按某个基数(通常为 2)的幂(称为指数)进行缩放。还有一个符号、 + 或 \xe2\x88\x92,尽管该符号有时包含在尾数中。
\n\n例如,使用二进制格式时,尾数 1.011 2在使用指数 0 缩放时表示 1+3/16 (1.011 2 \xe2\x80\xa22 0 = 1+3/16),在使用指数缩放时表示 11四个 (1.011 2 \xe2\x80\xa22 4 = 11),当以指数 \xe2\x88\x921 缩放时为 11/32 (1.011 2 \xe2\x80\xa22 \xe2\x88\x921 = 11/ 32)。
\n\n有效数有固定位数。所以只能表示某些数字。执行任何算术时,精确的数学结果将四舍五入到最接近的可表示数字。(舍入的常见默认规则是四舍五入到最接近的可表示值,并且在平局的情况下四舍五入,使低位数字为偶数。)
\n\n例如,在尾数具有三位十进制数字的十进制格式中,请考虑添加数字 567 (5.67\xe2\x80\xa210 2 ) 和 789 (7.89\xe2\x80\xa210 2 )。结果是 1356,但是位数太多。因此它四舍五入为 1360 (1.36\xe2\x80\xa210 3 )。舍入误差为 4。
\n\n因此,在处理浮点数时,会存在舍入误差,这些误差是尾数中最低有效数字的位置值的一部分。当数字的指数越大时,可能的误差就越大。误差始终在零和最低有效数字位置值的一半之间(因为两个可表示数字之间的任何数字要么位于中点,要么更接近其中之一,因此永远不需要将数字移动超过一半)可表示数字之间的距离。)
\n\n因此,当处理较大数字时,舍入误差较大。
\n| 归档时间: |
|
| 查看次数: |
1457 次 |
| 最近记录: |