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の35行目は

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

ここで、ndxは渡されるインデックスです。したがって、ndxはsub2indからの呼び出しを介して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

もう少し考えて、特にすべてを刺激した初心者のコメントを探しています。

つまり、これが重要です。シングルは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 に答える