这是一个与sub2ind / ind2sub相关的错误吗?

时间:2012-04-18 15:06:34

标签: matlab

我试图在单精度变量上做sub2ind,我遇到了以下奇怪的行为。例如,当我尝试:

[a b] = ind2sub([50000 50000], sub2ind([50000 50000], single(1000), single(1000)))

我明白了:

a = 1001
b = 1000

这是一个错误还是我遗漏了什么?我知道这可能是因为matlab代码中某处出现了溢出,但不应该发生,对吗?

我从64位(glnxa64)R2012a,R2011a,R2010b,R2010a得到了相同的错误行为,但是从32位(glnx86)R2010b获得了正确的结果。

2 个答案:

答案 0 :(得分:6)

发生这种情况的原因如下。

ind2sub.m的第35行是

vi = rem(ndx-1, k(i)) + 1;   

其中ndx是传入的索引。因此,通过sub2ind的调用,ndx为49951000。现在,当您传入单个精度值时,它会强制matlab以单精度计算所有数学运算。因此,比较l.35上发生的事情的差异。

K>> 49951000-1
ans =
        49950999

K>> single(49951000)-1
ans =
        49951000

从大数字中减去一小部分是个问题。所以不,这不是一个错误,它是对单精度浮点精度的限制。 This might help some.

编辑:正如拉斯曼所指出的,一种很好的展示方式是使用eps

eps(single(49951000))=4

因此,从单一(49951000)中添加或减去范围(-4,4)上的任何值将导致返回495100,因为单精度的准确性。

答案 1 :(得分:1)

一直在思考更多,尤其是寻找引发一切的gnovice评论。

所以这就是事情:单个是32位带符号的浮点数。因此,限制您获取数据的精确程度

eps(single(49951000)) = 4,而eps(single(50000^2)) = 256

因此你的范围是关闭的,尤其是当你增加指数值时,你会得到量化:

for i = 1000:1010
    sub2ind([50000 50000], single(i), single(1000))
end

如果你真的想要32位数字,我建议你使用uint32,因为你将能够代表所有数据点(50000的方形矩阵有2.5e + 09数据点> 2 ^ 32(= 4.3) e9))。

for i = 1000:1010
    sub2ind([50000 50000], uint32(i), uint32(1000))
end