我想我在Matlab中发现了一个错误。我唯一的解释是,matlab内部计算的值不是显示的值:
K>> calc(1,11)
ans =
4.000000000000000
K>> floor(ans)
ans =
3
显示的代码是Matlab控制台的输出。 calc(x,y)只是一个double值数组。
答案 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