Matlab地板虫?

时间:2012-09-26 21:41:38

标签: matlab floating-point rounding precision

我想我在Matlab中发现了一个错误。我唯一的解释是,matlab内部计算的值不是显示的值:

K>> calc(1,11)

ans =

   4.000000000000000

K>> floor(ans)

ans =

     3

显示的代码是Matlab控制台的输出。 calc(x,y)只是一个double值数组。

3 个答案:

答案 0 :(得分:8)

MATLAB使用标准的IEEE浮点形式来存储双精度。

如果我们从4中减去一小部分数量,那么MATLAB的结果仍然是4。

>> format long g
>> 4 - eps(2)
ans =
                         4

实际上,MATLAB以二进制形式存储数字。我们可以看到该数字的十进制版本:

>> sprintf('%.55f',4-eps(2))
ans =
3.9999999999999995559107901499373838305473327636718750000

显然,MATLAB不应该显示整个数字,但是通过将结果四舍五入到15位,我们得到4为显示。

显然,calc(1,11)中的值是这样一个数字,内部表示为小于4,只是头发太小而不能显示为4,但它不是4。

永远不要相信浮点算术中结果的最低显示数字。

编辑:

你似乎认为MATLAB中的3.999999999999999应该小于4.逻辑上,这是有道理的。但是当你提供这个号码时会发生什么?是的,浮点数double的粒度大于此值。 MATLAB不能将它表示为小于4的数字。它在内部将该数字向上舍入为完全4。

>> sprintf('%.55f',3.9999999999999999)
ans =
4.0000000000000000000000000000000000000000000000000000000

答案 1 :(得分:3)

你得到的是一个非常接近但低于4的值,即使使用format long,Matlab必须舍入到第15位来显示数字。 试试这个:

format long
asd = 3.9999999999999997 %first not-9 @16th digit

将打印4.000000000000000。任何根据可视化内容不知道asd的实际价值的人都会猜到它至少为4,但正在运行

asd >= 4

提供0,因此floor(asd)会返回3

因此,Matlab如何舍入显示的输出,存储在变量中的真值小于4。

<强>更新

如果你进一步使用数字,例如18x9:

>> asd = 3.999999999999999999
asd = 
     4
>> asd == 4
ans =
     1

asd正好成为4! (注意它不再显示4.000000000000000)但那是另一个故事,不再是围绕数字来获得更漂亮的输出,而是关于浮点运算如何工作......实数可以表示为一定的相对精度:在这种情况下,你给出的数字是如此接近4,它本身变成4。请查看@gokcehan或here评论中发布的Python链接。

答案 2 :(得分:1)

我不会解决问题,而是提供解决方案:使用single功能:

  

B = single(A)将矩阵A转换为单精度,在B中返回该值.A可以是任何数字对象(例如double)。如果A已经是单精度,则单个无效。单精度数量比双精度数量需要更少的存储量,但精度更低,范围更小。

这只是为了解决这个特定问题,所以你可以这样做:

K>> calc(1,11)

ans =

   4.000000000000000

K>> floor(single(ans))

ans =

 4