如何解决关于浮点精度:为什么迭代次数不相等?
| 有两个类似的matlab程序,一个重复10次,另一个重复11次。 一:i = 0;
x = 0.0;
h = 0.1;
while x < 1.0
i = i + 1;
x = i * h;
disp([i,x]);
end
另一个:
i = 0;
x = 0.0;
h = 0.1;
while x < 1.0
i = i + 1;
x = x + h;
disp([i,x]);
end
我不明白为什么浮点加法运算和倍数运算有区别。
解决方法
比较以下内容的输出:
>> fprintf(\'%0.20f\\n\',0.1.*(1:10))
0.10000000000000001000
0.20000000000000001000
0.30000000000000004000
0.40000000000000002000
0.50000000000000000000
0.60000000000000009000
0.70000000000000007000
0.80000000000000004000
0.90000000000000002000
1.00000000000000000000
>> fprintf(\'%0.20f\\n\',cumsum(repmat(0.1,1,10)))
0.10000000000000001000
0.20000000000000001000
0.30000000000000004000
0.40000000000000002000
0.50000000000000000000
0.59999999999999998000
0.69999999999999996000
0.79999999999999993000
0.89999999999999991000
0.99999999999999989000
还要与使用MATLAB \的COLON运算符进行比较:
>> fprintf(\'%0.20f\\n\',0.1:0.1:1)
0.10000000000000001000
0.20000000000000001000
0.30000000000000004000
0.40000000000000002000
0.50000000000000000000
0.59999999999999998000
0.69999999999999996000
0.80000000000000004000
0.90000000000000002000
1.00000000000000000000
如果要查看64位二进制表示形式,请使用:
>> format hex
>> [(0.1:0.1:1)\' (0.1.*(1:10))\' cumsum(repmat(0.1,10,1))]
3fb999999999999a 3fb999999999999a 3fb999999999999a
3fc999999999999a 3fc999999999999a 3fc999999999999a
3fd3333333333334 3fd3333333333334 3fd3333333333334
3fd999999999999a 3fd999999999999a 3fd999999999999a
3fe0000000000000 3fe0000000000000 3fe0000000000000
3fe3333333333333 3fe3333333333334 3fe3333333333333
3fe6666666666666 3fe6666666666667 3fe6666666666666
3fe999999999999a 3fe999999999999a 3fe9999999999999
3feccccccccccccd 3feccccccccccccd 3feccccccccccccc
3ff0000000000000 3ff0000000000000 3fefffffffffffff
一些建议的读物(与MATLAB相关):
Cleve \'s Corner 1996年文章
一瞥浮点数
准确性
我如何确定错误
我的答案是四舍五入的结果
错误还是错误?
COLON运算符如何
工作?
, 使用浮点计数器进行迭代时,应该非常小心。仅作为示例,我将向您展示您的情况(这是一个Java程序,但您的情况应该相同):单击此处自行运行
double h = 0.1;
System.out.println(10*h-1.0);
System.out.println(h+h+h+h+h+h+h+h+h+h-1.0);
在进行乘法与单独加法时,它只是将差值打印为一个。
由于浮点数的表示形式不准确,因此结果如下所示:
0.0
-1.1102230246251565E-16
因此,如果在后一种情况下将其用作循环条件,则将进行额外的迭代(尚未达到一个迭代)。
尝试使用计数器变量i
,它是一个整数,因此您不会遇到此类问题。
, 浮点数的表示形式是精确的,除了浮点数算法以2为底,十进制数(例如0.1)具有无限的二进制扩展数。由于浮点数的位数有限,因此必须对0.1的无限扩展进行四舍五入,并且四舍五入误差会在加法时累积,从而导致差异。
但是,大多数浮点运算都不精确:结果通常需要比固定位数所能容纳的精度还要多的精度,因此CPU自动将结果舍入为可用精度。如您所注意到的,这种舍入误差会在较长的计算链中累积,有时会导致实际结果与“正确”结果之间存在巨大差异。 (将“正确”定义为在无限精度算法中获得的结果。)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。