web-dev-qa-db-ja.com

DoubleとIntを比較する最良の方法は何ですか?

C#の次のコードは機能しません。

int iValue = 0;
double dValue = 0.0;

bool isEqual = iValue.Equals(dValue);

だから、質問:DoubleとIntを比較するための最良の方法は何ですか?

浮動小数点値と積分値を単純な方法で比較することは実際にはできません。特に、古典的な 浮動小数点表現の課題 があるので。あなたができることは、一方を他方から減算し、それらの間の差があなたが気にかけている精度よりも小さいかどうかを確認することです。

int iValue = 0;
double dValue = 0.0;

var diff = Math.Abs(dvalue - iValue);
if( diff < 0.0000001 ) // need some min threshold to compare floating points
   return true; // items equal

equalityがあなたにとって何を意味するかを自分で定義する必要があります。たとえば、浮動小数点値を最も近い整数に丸めて、3.999999991が4に「等しく」なるようにしたい場合や、値を切り捨てて事実上3になるようにしたい場合があります。これはすべて、ユーザーによって異なります。達成しようとしています。

EDIT:しきい値の例として0.0000001を選択したことに注意してください...比較に十分な精度を自分で決定する必要があります。 doubleの通常の表現範囲内にいる必要があることを理解してください。これはDouble.Epsilonとして定義されていると思います。

50
LBushkin

整数と浮動小数点数を比較して、どの言語でも同等であるかどうかを比較するのは非常に悪い考えです。これは非常に単純なケースで機能しますが、数学を実行した後は、プログラムが実行したいことを実行する可能性が劇的に低下します。

これは、浮動小数点数がバイナリのデジタルシステムに格納される方法と関係があります。

これを使用することが確実な場合は、クラスを作成して、分数を使用して独自の数を作成してください。 1つのintを使用して整数を維持し、別のintを使用して分数を維持します。

4
San Jacinto

これは本当にあなたが「等しい」と考えるものに依存します。 doubleが整数値と正確に一致する場合(つまり、小数成分がない場合)にのみ比較をtrueに戻す場合は、intをdoubleにキャストして比較を行う必要があります。

bool isEqual = (double)iValue == dValue;

1.1のようなものが1に等しいと見なされる場合は、doubleをintにキャストするか(小数部分を完全に無視する場合)、1.9を2に等しくする場合はdoubleを丸めることができます。

1
Ryan Brunner

差出人 https://docs.Microsoft.com/en-us/dotnet/api/system.double.equals?view=netframework-4.8#System_Double_Equals_System_Double_

Epsilonは、範囲がゼロに近い正の値の最小式を定義するため、2つの類似した値の差のマージンはEpsilonより大きくなければなりません。通常、それはイプシロンより何倍も大きいです。このため、Double値を比較して等しいかどうかを比較する場合は、Epsilonを使用しないことをお勧めします。

0
Milan Vylita

今日では、タイプdoubleintegerまたはlongのいずれかの値を厳密に等しくするために比較する必要があるのは、何らかの理由で格納または整数値を浮動小数点値として渡し、後でそれらを元に戻す必要があります。このような変換は、ほとんどの場合、整数型をdoubleにキャストし、そのキャストの結果を比較することで最も簡単に実行できます。数値が±2の範囲外の場合、longからdoubleへの変換が不正確になる可能性があることに注意してください。52。それにもかかわらず、64ビットのlongが利用可能になる前の数日間、doubleは、32ビットのintには大きすぎるが、十分に小さい整数量の便利なストレージタイプでした。 doubleによって処理されます。

longdoubleに変換してから比較を行うと、doubleの公称値がlong valueですが、その値に可能な限り最も近いdoubleを表します。この動作は、浮動小数点型が実際には単一の正確な値ではなく、値の範囲を表すことを認識している場合に意味があります。

0
supercat
double val1 = 0;
double val2 = 0.0;
if((val1 - Double.Epsilon) < 0)
{
    // Put your code here
}

      OR

if((val2 - Double.Epsilon) < 0)
{
    // Put your code here
}

ここで、Double.EpsilonはDoubleの可能な最小値です。

0
Jatin