4

私は適応型の「ほぼ等しい」メソッド(C#で書かれていますが、質問は一般的です)を作成しようとしています.2つのdoubleを受け入れ、「ほぼ等しい」かどうかブール値を返します。アダプティブとは、次のことを意味します。

1.234 および 1.235 ==> TRUE

しかし

1.234567 および 1.234599 ==> FALSE

つまり、「ほぼ等しい」の精度は、数値の精度に適応します。

2 つの変数がほぼ等しいかどうかを調べるにはどうすればよいですか?で丸めの概念を見つけました。しかし、イプシロンに何を使用するかという未解決の問題がまだあります。

この種の問題のベストプラクティスを知っている人はいますか? 前もって感謝します!

編集: 私の最初の質問には、取得しようとしていたものに関する十分な情報が含まれていませんでした。申し訳ありません。より高い精度の数値をより高い基準で扱い、より低い精度の数値に対してより寛大になるプログラムが必要です。ペアのその他の例は次のとおりです (「(0)」は暗黙のゼロです)。

1.077 および 1.07(0) は false を返します (77 は 70 と大きく異なるため)

1.000077 および 1.00007(0) は false を返します (77 は 70 とは大きく異なるため)

1.071 および 1.07(0) は true を返します (71 は 70 に近いため)

1.000071 および 1.00007(0) は true を返します (71 は 70 に近いため)

実装コードに関係なく、「非常に異なる」ものと「近い」ものを判断するための何らかの「許容範囲」変数があると思います。

4

3 に答える 3

5

浮動小数点数を比較する1つの方法は、それらを区切る浮動小数点表現の数を比較することです。このソリューションは数値のサイズに影響されないため、「イプ​​シロン」について心配する必要はありません。

アルゴリズムの説明はここ(最後にAlmostEqual2sComplement関数)にあり、これが私のC#バージョンです。

public static class DoubleComparerExtensions
{
    public static bool AlmostEquals(this double left, double right, long representationTolerance)
    {
        long leftAsBits = left.ToBits2Complement();
        long rightAsBits = right.ToBits2Complement();
        long floatingPointRepresentationsDiff = Math.Abs(leftAsBits - rightAsBits);
        return (floatingPointRepresentationsDiff <= representationTolerance);
    }

    private static unsafe long ToBits2Complement(this double value)
    {
        double* valueAsDoublePtr = &value;
        long* valueAsLongPtr = (long*)valueAsDoublePtr;
        long valueAsLong = *valueAsLongPtr;
        return valueAsLong < 0
            ? (long)(0x8000000000000000 - (ulong)valueAsLong)
            : valueAsLong;
    }
}

フロートを比較する場合は、alldoublefloat、all longto int、および0x8000000000000000に変更し0x80000000ます。

于 2012-05-02T19:00:43.867 に答える
0

一方を他方で割り、結果が 1 に近いかどうかを確認できます。

var ratio = a / b;
var diff = Math.Abs(ratio - 1);
return diff <= epsilon;

次に、イプシロンを選択して、値がどれだけ近いかを決定する必要があります。

ただし、あなたの例では、最初の例は 0.08% の差ですが、2 番目の例は 0.003% の差ですが、最初の例は真で、2 番目の例は偽である必要があります。あなたが本当に何を探しているのかわかりません。問題の解決策を決定する前に、それを知る必要があります。(正しい答えを得る前に、正しい質問が必要です) 「最後の有効桁数は異なる可能性がありますが、それ以上は変わらない」というようなことを想像するかもしれませんが、それを数学的に定義することはそれほど単純ではありません。たとえば、0.49999999997 は 0.5 に等しいでしょうか? 0.500000000003 はどうでしょうか。数値を比較することはどのように意味がありますか?

于 2012-05-02T18:48:27.130 に答える