1. ホーム
  2. c#

C#の浮動小数点比較関数

2023-08-26 17:51:48

質問

誰かC#で浮動小数点値を比較するための良い一般的な浮動小数点比較関数を指し示す(または示す)ことができますか?私は IsEqual , IsGreater アン IsLess . また、私は浮動小数点数ではなく、倍数のみを本当に気にします。

どのように解決するのですか?

便利な汎用浮動小数点の書き方 IsEqual を書くことは、完全に不可能ではないにしても、とてもとても難しいことです。現在のコードでは a==0 . このような場合にメソッドがどのように動作すべきかは、実際には定義の問題であり、間違いなく、コードは特定のドメインのユースケースに合わせて調整されるのが最善でしょう。

この種のものに対して、あなたは が本当に、本当に必要です。 が必要です。これは、私が 浮動小数点演算ガイド のために行った方法で、これが最終的に私が考え出したものです(Javaコード、翻訳するのは十分に簡単でしょう)。

public static boolean nearlyEqual(float a, float b, float epsilon) {
    final float absA = Math.abs(a);
    final float absB = Math.abs(b);
    final float diff = Math.abs(a - b);

    if (a == b) { // shortcut, handles infinities
        return true;
    } else if (a == 0 || b == 0 || absA + absB < Float.MIN_NORMAL) {
        // a or b is zero or both are extremely close to it
        // relative error is less meaningful here
        return diff < (epsilon * Float.MIN_NORMAL);
    } else { // use relative error
        return diff / (absA + absB) < epsilon;
    }
}

また のテストスイートもあります。 .

付録です。 倍数のためのc#の同じコード(質問で尋ねられたように)

public static bool NearlyEqual(double a, double b, double epsilon)
{
    const double MinNormal = 2.2250738585072014E-308d;
    double absA = Math.Abs(a);
    double absB = Math.Abs(b);
    double diff = Math.Abs(a - b);

    if (a.Equals(b))
    { // shortcut, handles infinities
        return true;
    } 
    else if (a == 0 || b == 0 || absA + absB < MinNormal) 
    {
        // a or b is zero or both are extremely close to it
        // relative error is less meaningful here
        return diff < (epsilon * MinNormal);
    }
    else
    { // use relative error
        return diff / (absA + absB) < epsilon;
    }
}