关于Matlab中浮点运算的问题

Question about floating-point arithmetic in Matlab

提问人:Questioner5453 提问时间:11/15/2022 最后编辑:Questioner5453 更新时间:11/15/2022 访问量:91

问:

当我在 Matlab 中计算以下内容时

myeps = abs(3*(4/3-1)-1);
format long e
eps_myeps = [eps ; myeps]

输出如下:

eps_myeps =

     2.220446049250313e-16
     2.220446049250313e-16

为什么不是 0?为什么当基数是 3 而不是 2 时,这不成立?myeps

MATLAB 浮点 精度

评论

0赞 Luis Mendo 11/15/2022
myeps由于浮点不准确,因此不为零。同样的原因为什么不给零。更多信息请点击此处。你问题的第二部分,为什么当基数是 3 而不是 2 时,这不成立,尚不清楚。你到底是什么意思?请相应地编辑问题。请注意,2 的幂(不太大或太小)确实具有精确的表示形式,如链接中所述;也许这解释了你的第二个问题sin(pi)

答:

2赞 chux - Reinstate Monica 11/15/2022 #1

代码在数学中是 4/3,4/3 不能完全编码为浮点数。 大多数浮点数是二元有理数(整数乘以 2 的幂),并使用邻近值。*1就像我们不能完全用十进制写 4/3 一样,只能写 1.3333333 并在这么多数字后停止。4/3

在这种情况下,减法以及乘法和最终减法应该是精确的。然而,第一个商不是 4/3,因此最终结果可能不是 0.0。


*1
十进制 1.333333333333333332593184650249895639717578887939453125
十六进制0x1.5555555555555

评论

0赞 Questioner5453 11/15/2022
为什么这个错误只发生在基数 2 和 10 中?为什么它不发生在基数 3 中?
1赞 chux - Reinstate Monica 11/15/2022
@Questioner5453 它不会出现在以 3 为基数的中,因为这里的除法是 3 - 而且非常准确。如果这里的除法是 5,它确实发生在基数 3 中。哎呀,除数能被底数整除吗?
1赞 chux - Reinstate Monica 11/15/2022
@Questioner5453 尝试在纸上只使用有限大小的十进制数,也许是 5 位数字:4/3 --> 1.3333。1.3333 - 1.0000 --> 3.3330.3.0000* 3.3330e-1 --> 9.9990e-1.9.9990e-1 - 1.0000 --> -1.0000e-4 而不是零。以 2 为基数的浮点数也会发生同样的事情 - 只是更多的数字。注意:2.220446049250313e-16 是 power(2, -52)。3*(4/3-1)-1
0赞 X Zhang 11/15/2022 #2

我觉得 OP 也在寻找“如何获得 0 作为答案”的答案,此外 “为什么myeps不是0”。所以这就是答案。您将需要 Symbolic Math Toolbox for MATLAB。

可以使用符号创建符号数字。符号数字是 精确表示,与浮点数不同。

因此,如果您输入 MATLAB(一旦您获得工具箱),答案将是准确的3*(sym(4)/sym(3)-1)-1

0

只介意那部分。如果您尝试,MATLAB 将首先获得一个浮点,然后尝试将其转换为符号。这将失去精度,并且不会产生 0 作为答案。sym(4)/sym(3)sym(4/3)

评论

1赞 James Tursa 11/15/2022
更正:实际上,3*(sym(4/3)-1)-1 在 MATLAB 中将恰好产生 0,因为 sym 引擎有一种算法,可以将从 p/q 计算的浮点值转换为“中等大小的整数 p 和 q”的正好 p/q。但是,不应依赖这一点,如上所示,首先单独转换整数或使用字符串进行整数除法(如“4/3”)是要走的路。
0赞 X Zhang 11/15/2022
@JamesTursa 你是对的,那么你又是对的。我的意思是 3*(sym(4/3)-1)-1 确实产生 0,但 sym(3*(4/3-1)-1) 会产生一些非零分数。因此,安全总比不可预测要好。