2

我试图对遇到以下奇怪行为的单精度变量执行 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 得到正确的结果。

4

2 回答 2

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

从大数中减去小数是问题所在。所以不,这不是错误,它是对单精度浮点精度的限制。这可能会有所帮助。

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

eps(single(49951000))=4

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

于 2012-04-18T15:35:09.593 回答
1

一直在思考更多,尤其是看着一个新手的评论引发了一切。

所以事情是这样的:single 是一个 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.3e9))。

for i = 1000:1010
    sub2ind([50000 50000], uint32(i), uint32(1000))
end
于 2012-04-18T17:22:00.370 回答