ダブル。イプシロンのための平等以上未満以上または同等以上の

StackOverflow https://stackoverflow.com/questions/2411392

  •  18-09-2019
  •  | 
  •  

質問

http://msdn.microsoft.com/en-us/library/system.double.epsilon.aspx

作成した場合は、カスタムアルゴリズム かどうかを判定し二つの浮動小数点 数が等しいと見なされる、 を使用する必要がある値以上で のイプシロンを一定の確立 可絶縁 差の値にする と同じです。(通常は、 証拠金の差は多くの 以上のイプシロン.)

っているのではないだろうか本当には、イプシロンを用いて比較?思にMSDN言葉.

使用できるのは、イプシロンの例。- その中で最も効果的な方法は、floatおよびdouble性リスクアセスメント

最後にこの大切そうというのもいい着実な実施のための平等以上未満,以下、以上。

役に立ちましたか?

解決

私は、彼らがそれを書いたときは、彼らが喫煙していたもののか分かりません。 Double.Epsilonは、あなたが知っているすべては、打ち切り誤差がある場合、それは常にこの値よりの大きくなり、ということである0でない最小の表現非デノーマル浮動小数点値です。はるかに大きいます。

System.Double型は、最大15桁まで正確な値を表すことができます。そう単純な一次推定二値xが何らかの定数に等しい場合、一定のイプシロンを使用することである* 1E-15

public static bool AboutEqual(double x, double y) {
    double epsilon = Math.Max(Math.Abs(x), Math.Abs(y)) * 1E-15;
    return Math.Abs(x - y) <= epsilon;
}

あなたはしかし、注目する必要がある、切り捨てエラーが蓄積することができます。 xyの両方が値を計算しているなら、あなたはイプシロンを増やす必要があります。

他のヒント

  

私は以下に等しい、とより大きいか等しい、より小さく、より大きな平等のための強固な実装を持っていることを確認したいと思います。

あなたは2進浮動小数点演算を使用しています。

2進浮動小数点演算のように長さ、質量、電荷、時間など物理量を表すように設計され、そしてた。

おそらく、あなたは、それが使用されることが意図されたように2進浮動小数点演算を使用している:物理量に演算を実行する

の物理量の測定は、常にそれらを測定するために使用される装置の精度に依存して、特定の精度を有している。

あなたが操作している量の値を提供する1つであるため、

、あなたは、「エラーバー」は、その量にあるかを知っている一つです。あなたは数量を提供している場合たとえば、あなたは、これはセンチメートルではなく、マイクロメートルの精度であることを知っています。

その後、「建物の高さは123.56メートルです」 平等のための2つの量を比較した場合、

したがって、所望のセマンティクスは言うことである「これら二つの量は、各測定で指定されたエラーバー内等しい?」

だから今、私たちはあなたの質問への答えを持っています。あなたがしなければならないとすると、エラーが各数量に何であるかを追跡することです。例えば、建物の高さは「123.56メートルの0.01以内に」あなたはその測定がどのように正確である知っているからです。あなたは123.5587である別の測定を取得し、二つの測定は誤差の許容範囲内で「等しい」かどうかを知りたい場合は、減算を行うと、それが許容誤差に該当するかどうかを確認します。この場合、それはありません。測定は、実際にはマイクロメートルまで正確であった場合、それらは等しくありません。

要するに:あなたはあなたが操作されている数字は、最初の場所でどこから来たのかを知っている人だけですので、あなたは、賢明な許容誤差が何であるかを知っているここでの唯一の人です。許容誤差は、あなたの測定のために理にかなっているものは何でも使用して、あなたがそれを生成するために使用される機器の精度を与えられます。

あなたが1.0に近い2つのdouble値を持っているが、彼らが唯一の彼らの最下位ビットが異なる場合は、

、その後、両者の差がDouble.Epsilonより大きい数桁になります。実際には、その差は大きさの324回の小数の注文です。これは、指数部分の効果です。 1.0(コースのバイアスが除去された後、)ゼロの指数を有しているDouble.Epsilonは、その上に大きな負の指数を有する。

あなたが平等のための2つの類似した値を比較したい場合は、あなたが比較される値のオーダー・オブ・大きサイズに適しているカスタムイプシロン値を選択する必要があります。

あなたが比較している二重の値が1.0付近である場合。そして、少なくともsiginificantビットの値は0.0000000000000001に近いだろう。あなたが比較している二重の値はquadrillionsにある場合、最下位ビットの値が千限りである可能性があります。イプシロンのための単一の値は、これらの状況の両方において等価比較のために使用することができなかった。

私はこれをしなかった - ケントBogartsのアイデアを使用して

private bool IsApproximatelyEqual(double x, double y, double acceptableVariance)
{
     double variance = x > y ? x - y : y - x;
     return variance < acceptableVariance;

     //or
     //return Math.Abs(x - y) < acceptableVariance;
}

これは、次の2つの値のいずれかを正確に等しい、またはdouble型の最小表現の違いがあることを確認したいと仮定すると、比較のために使用することができます。一般的に次の2つのdoubleがほぼ等しいかどうかを確認するためにdouble.Epsilonよりも大きい番号を使用したい、話してます。

.NETフレームワークは、

のようなものを定義していないのはなぜ
bool IsApproximatelyEqual(double value, double permittedVariance);

私を超えている。

私はあなたが投稿MSDNのリンクの該当ビットは、これらのしていると思います

  

しかし、イプシロンのプロパティではありません   の精度の一般的な指標   ダブルタイプ。それは二重にのみ適用されます   ゼロの価値を持つインスタンスます。

     

注:イプシロンの値   プロパティは、マシンと等価ではありません   上部を表しイプシロン、   相対誤差の原因にバインド   浮動小数点演算で丸めます。

     

この値は、最小として定義されていません   正の数X、例えばX + 1.0という   1.0に等しくないので、Double.Epsilon   「ほとんど平等」のために使用することはできません。   には定数が存在しません   その値が最小となるフレームワーク   正の数X、例えばX + 1.0という   1.0に等しいではありません。

私は私を驚かせること、言わなければなりません。明確ではない - 私はあまりにもDouble.Epsilonは、C / C ++でDBL_EPSILONの同等であったと仮定していました!

私はそれは控えめに言って、むしろ驚くべきことである「あなたは比較のためにまともな値を自分で把握する必要があり」と言っているように見えるそのリンクを読むことができるものから。
おそらく、より多くの知識豊富誰かが明確にすることができます)。

私が使用して次の

public static class MathUtil {
    /// <summary>
    /// smallest such that 1.0+EpsilonF != 1.0
    /// </summary>
    public const float EpsilonF = 1.192092896e-07F;

    /// <summary>
    /// smallest such that 1.0+EpsilonD != 1.0
    /// </summary>
    public const double EpsilonD = 2.2204460492503131e-016;

    [MethodImpl( MethodImplOptions.AggressiveInlining )]
    public static bool IsZero( this double value ) {
        return value < EpsilonD && value > -EpsilonD;
    }

    [MethodImpl( MethodImplOptions.AggressiveInlining )]
    public static int Sign( this double value ) {
        if ( value < -EpsilonD ) {
            return -1;
        }
        if ( value > EpsilonD )
            return 1;
        return 0;
    }

あなたは2倍に「a」と「b」の等価性をチェックしたい場合は、あなたが使用することができます。

(a-b).IsZero();

あなたは、比較結果を取得したい場合や、使用

(a-b).Sign();

の問題との比較を兼ねがいとの比較二つの異なる数学の成果が等しいものの、四捨五入の誤りにくいのではないでしょうか"の評価を同じ値に、一部のサ---以上のイプシロン、端にある。とが信頼のおけるε値が難しかったですね。もう二倍に等しい場合はこれらの差額については、以下の何割かは、価値からを用いた静的な最低限の差εあるというわけでは差が小さすぎたり大きのダブル自体が高い又は低い。

ここでのSilverlightコントロールツールキット以内に2回含まれるいくつかのコードです

    public static bool AreClose(double value1, double value2)
    {
        //in case they are Infinities (then epsilon check does not work)
        if(value1 == value2) return true;
        // This computes (|value1-value2| / (|value1| + |value2| + 10.0)) < DBL_EPSILON
        double eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * DBL_EPSILON;
        double delta = value1 - value2;
        return(-eps < delta) && (eps > delta);
    }

一つの場所では、彼らはイプシロンのため1e-6を使用します。他に彼らが1.192093E-07を使用しています。あなたはあなた自身のイプシロンを選ぶことになるでしょう。

あなたはそれを自分で計算するか、独自の定数を定義する必要は選択の余地はありません。

double calculateMachineEpsilon() {
    double result = 1.0;
    double one = 1.0/256;

    while(one + result/2.0 != 1.0) {
        result/=2.0;
    }
    return result;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top