2

浮動小数点値に非常に小さな値を追加して、同等性テストに失敗するように、わずかな違いにする必要があります。

精度の問題を避けるために、非常に小さな数を追加する代わりに、比較的小さな数を追加することにしました。これは良い解決策ですか?または、さらに小さい数を追加する信頼できる方法はありますか?

matrix.m00 += matrix.m00 * 0.0000001f;
matrix.m11 += matrix.m11 * 0.0000001f;
matrix.m22 += matrix.m22 * 0.0000001f;

読んだ結果、最良の解決策は次の表現可能な浮動小数点数を使用することであることがわかりました。ただし、C# では、これを行うプロセスには、a) 管理されていない/安全でないコードが必要であるか、b)BitConverter遅すぎるコードを使用しています。したがって、上記の解決策が機能すると考えましたが、問題があるかどうかを知りたいです。

4

3 に答える 3

3

ulpは任意のdoubleに追加できます(doubleによって異なります)。これは、値を変更するために加算または減算できる最小の数値です。

ただし、これらの投稿はすべてを使用しますBitConverter。安全でないコードなしでulpを追加する方法について説明している投稿を発見しましたBitConverter

http://realtimemadness.blogspot.com/2012/06/nextafter-in-c-without-allocations-of.html

于 2013-02-23T01:28:29.380 に答える
1

別の数が生成されるように浮動小数点数に追加できる最小数は、元の数の関数であり、一定ではありません。この関数を呼び出しますEpsilon(x)

Epsilon(0)、つまり、識別可能な数が生成されるように浮動小数点0に追加できる最小浮動小数点数は、静的値で見つけることができますDouble.Epsilon

ただし、1のような「大きな」イプシロンを使用しても、最終的には失敗します。たとえば、これはC#でtrueを返します。

var big = 10000000000000000.0;
Console.WriteLine(big == (big + 1.0));

したがって、入力が一定の大きさの範囲(たとえば、すべて0に近い)にあることが確実でない限り、単一の定数でそれをファッジすることはできません。

于 2013-02-23T01:41:08.920 に答える
1

確かに落とし穴があります。これらの値のいずれかが 0 の場合、正確に 0 を追加します。つまり、値をまったく変更しません。

安全でないコードを使用してこれを行うことができなかった理由はありますか?

于 2013-02-23T01:26:10.883 に答える