我试图在单精度变量上做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获得了正确的结果。
答案 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