Double.Equals メソッド

定義

Double の 2 つのインスタンスが同じ値を表しているかどうかを示す値を返します。

オーバーロード

Equals(Double)

このインスタンスと指定した Double オブジェクトが同じ値を表しているかどうかを示す値を返します。

Equals(Object)

このインスタンスが指定されたオブジェクトに等しいかどうかを示す値を返します。

Equals(Double)

このインスタンスと指定した Double オブジェクトが同じ値を表しているかどうかを示す値を返します。

public:
 virtual bool Equals(double obj);
public bool Equals (double obj);
override this.Equals : double -> bool
Public Function Equals (obj As Double) As Boolean

パラメーター

obj
Double

このインスタンスと比較する Double オブジェクト。

戻り値

Boolean

obj がこのインスタンスと等しい場合は true。それ以外の場合は false

実装

注釈

このメソッドはインターフェイスを実装し、パラメーターを System.IEquatable<T> オブジェクトに変換する必要がないため、少し優れた Equals パフォーマンスを obj 発揮します。

拡大変換

プログラミング言語によっては、パラメーター型のビット数がインスタンス型よりも少ない (狭い) メソッドをコーディング Equals できる場合があります。 これは、一部のプログラミング言語では、インスタンスと同数のビットを持つ型としてパラメーターを表す暗黙的な拡大変換を実行するためです。

たとえば、インスタンスの型が 〗で Double 、パラメーターの型が 〘 であると Int32します。 Microsoft C# コンパイラは、パラメーターの値をオブジェクトとして Double 表す命令を生成し、インスタンスの値とパラメーターの拡大表現を比較するメソッドを生成 Double.Equals(Double) します。

コンパイラが数値型の暗黙的な拡大変換を実行するかどうかを判断するには、プログラミング言語のドキュメントを参照してください。 詳細については、「 型変換テーブル」 トピックを参照してください。

比較の精度

このメソッドは Equals 、2 つの値の精度が異なるため、2 つの明らかに同等の値が等しくない可能性があるため、注意して使用する必要があります。 次の例では、 Double 値 .333333 と Double 1 を 3 で除算して返される値が等しくないことを報告します。

// Initialize two doubles with apparently identical values
double double1 = .33333;
double double2 = (double) 1/3;
// Compare them for equality
Console.WriteLine(double1.Equals(double2));    // displays false
// Initialize two doubles with apparently identical values
let double1 = 0.33333
let double2 = double (1 / 3)
// Compare them for equality
printfn $"{double1.Equals double2}"    // displays false
' Initialize two doubles with apparently identical values
Dim double1 As Double = .33333
Dim double2 As Double = 1/3
' Compare them for equality
Console.WriteLine(double1.Equals(double2))    ' displays False

等価性を比較するのではなく、1 つの手法では、2 つの値間の差の許容可能な相対マージン (値の 1 つの .001% など) を定義する必要があります。 2 つの値の差の絶対値がその余白以下の場合、その差は精度の違いによるものと考えられるため、値は等しい可能性があります。 次の例では、この手法を使用して .33333 と 1/3 を比較します。これは、前のコード例で等しくないことがわかった 2 つの Double 値です。 この場合、値は等しくなります。

// Initialize two doubles with apparently identical values
double double1 = .333333;
double double2 = (double) 1/3;
// Define the tolerance for variation in their values
double difference = Math.Abs(double1 * .00001);

// Compare the values
// The output to the console indicates that the two values are equal
if (Math.Abs(double1 - double2) <= difference)
   Console.WriteLine("double1 and double2 are equal.");
else
   Console.WriteLine("double1 and double2 are unequal.");
// Initialize two doubles with apparently identical values
let double1 = 0.333333
let double2 = double (1 / 3)
// Define the tolerance for variation in their values
let difference = abs (double1 * 0.00001)

// Compare the values
// The output to the console indicates that the two values are equal
if abs (double1 - double2) <= difference then
    printfn "double1 and double2 are equal."
else
    printfn "double1 and double2 are unequal."
' Initialize two doubles with apparently identical values
Dim double1 As Double = .33333
Dim double2 As Double = 1/3
' Define the tolerance for variation in their values
Dim difference As Double = Math.Abs(double1 * .00001)

' Compare the values
' The output to the console indicates that the two values are equal
If Math.Abs(double1 - double2) <= difference Then
   Console.WriteLine("double1 and double2 are equal.")
Else
   Console.WriteLine("double1 and double2 are unequal.")
End If

注意

範囲が 0 に近い正の値の最小式を定義するため Epsilon 、2 つの類似した値間の差の余白は Epsilon、 通常、この値は Epsilon.. このため、等しい値を比較Doubleする場合は使用Epsilonしないことをお勧めします。

2 つ目の手法では、2 つの浮動小数点数と絶対値の差を比較します。 差がその絶対値以下の場合、数値は等しくなります。 大きい場合、数値は等しくありません。 別の方法の 1 つは、絶対値を任意に選択する方法です。 ただし、許容できる差は値の大きさに依存するため、これは問題です Double 。 2 つ目の代替方法は、浮動小数点形式のデザイン機能を利用します。2 つの浮動小数点値の整数表現の違いは、それらを区切る可能な浮動小数点値の数を示します。 たとえば、0.0 と Epsilon 1 の差は、値が 0 の場合に最Doubleも小さい表現可能な値であるためEpsilonです。 次の例では、この手法を使用して .33333 と 1/3 を比較します。これは、前のコード例とEquals(Double)メソッドが等しくないことがわかった 2 つのDouble値です。 この例では、このメソッドを BitConverter.DoubleToInt64Bits 使用して倍精度浮動小数点値を整数表現に変換することに注意してください。

using System;

public class Example
{
   public static void Main()
   {
      double value1 = .1 * 10;
      double value2 = 0;
      for (int ctr = 0; ctr < 10; ctr++)
         value2 += .1;

      Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2,
                        HasMinimalDifference(value1, value2, 1));
   }

   public static bool HasMinimalDifference(double value1, double value2, int units)
   {
      long lValue1 = BitConverter.DoubleToInt64Bits(value1);
      long lValue2 = BitConverter.DoubleToInt64Bits(value2);

      // If the signs are different, return false except for +0 and -0.
      if ((lValue1 >> 63) != (lValue2 >> 63))
      {
         if (value1 == value2)
            return true;

         return false;
      }

      long diff = Math.Abs(lValue1 - lValue2);

      if (diff <= (long) units)
         return true;

      return false;
   }
}
// The example displays the following output:
//        1 = 0.99999999999999989: True
open System

let hasMinimalDifference (value1: double) (value2: double) (units: int) =
    let lValue1 = BitConverter.DoubleToInt64Bits value1
    let lValue2 = BitConverter.DoubleToInt64Bits value2

    // If the signs are different, return false except for +0 and -0.
    if (lValue1 >>> 63) <> (lValue2 >>> 63) then
        value1 = value2
    else
        let diff = abs (lValue1 - lValue2)

        diff <= int64 units

let value1 = 0.1 * 10.
let mutable value2 = 0.
for _ = 0 to 9 do
    value2 <- value2 + 0.1

printfn $"{value1:R} = {value2:R}: {hasMinimalDifference value1 value2 1}"
                

// The example displays the following output:
//        1 = 0.99999999999999989: True
Module Example
   Public Sub Main()
      Dim value1 As Double = .1 * 10
      Dim value2 As Double = 0
      For ctr As Integer =  0 To 9
         value2 += .1
      Next
               
      Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2,
                        HasMinimalDifference(value1, value2, 1))
   End Sub

   Public Function HasMinimalDifference(value1 As Double, value2 As Double, units As Integer) As Boolean
      Dim lValue1 As long =  BitConverter.DoubleToInt64Bits(value1)
      Dim lValue2 As long =  BitConverter.DoubleToInt64Bits(value2)
      
      ' If the signs are different, Return False except for +0 and -0.
      If ((lValue1 >> 63) <> (lValue2 >> 63)) Then
         If value1 = value2 Then
            Return True
         End If           
         Return False
      End If

      Dim diff As Long =  Math.Abs(lValue1 - lValue2)

      If diff <= units Then
         Return True
      End If

      Return False
   End Function
End Module
' The example displays the following output:
'       1 = 0.99999999999999989: True

文書化された有効桁数を超える浮動小数点数の精度は、.NET Frameworkの実装とバージョンに固有です。 したがって、数値の内部表現の精度が変化する可能性があるため、.NET Frameworkのバージョン間で 2 つの特定の数値の比較が変更される可能性があります。

メソッドを呼び出Equalsして 2 つのDouble.NaN値が等しいかどうかをテストすると、メソッドtrueは . ただし、等値演算子を使用して 2 つの NaN 値が等しいかどうかをテストした場合、演算子 falseは . a Double の値が数値 (NaN) ではないかどうかを判断する場合は、メソッドを呼び出 IsNaN す方法があります。

注意 (呼び出し元)

コンパイラ オーバーロードの解決では、2 つの Equals(Object) メソッド オーバーロードの動作の明らかな違いが考慮される場合があります。 引数と a Double の間のobj暗黙的な変換が定義されていて、引数が型指定Objectされていない場合、コンパイラは暗黙的な変換を実行してメソッドをEquals(Double)呼び出す可能性があります。 それ以外の場合は、引数がEquals(Object)値でない場合objに常に返falseされるメソッドをDouble呼び出します。 次の例は、2 つのメソッド オーバーロードの動作の違いを示しています。 C# を除くDecimalすべてのプリミティブ数値型の場合、最初の比較trueは、コンパイラが拡大変換を自動的に実行してメソッドを呼び出Equals(Double)すのに対し、2 番目の比較はメソッドを呼び出Equals(Object)すので返falseされます。

using System;

public class Example
{
   static double value = 112;

   public static void Main()
   {
      byte byte1= 112;
      Console.WriteLine("value = byte1: {0,16}", value.Equals(byte1));
      TestObjectForEquality(byte1);

      short short1 = 112;
      Console.WriteLine("value = short1: {0,16}", value.Equals(short1));
      TestObjectForEquality(short1);

      int int1 = 112;
      Console.WriteLine("value = int1: {0,18}", value.Equals(int1));
      TestObjectForEquality(int1);

      long long1 = 112;
      Console.WriteLine("value = long1: {0,17}", value.Equals(long1));
      TestObjectForEquality(long1);

      sbyte sbyte1 = 112;
      Console.WriteLine("value = sbyte1: {0,16}", value.Equals(sbyte1));
      TestObjectForEquality(sbyte1);

      ushort ushort1 = 112;
      Console.WriteLine("value = ushort1: {0,16}", value.Equals(ushort1));
      TestObjectForEquality(ushort1);

      uint uint1 = 112;
      Console.WriteLine("value = uint1: {0,18}", value.Equals(uint1));
      TestObjectForEquality(uint1);

      ulong ulong1 = 112;
      Console.WriteLine("value = ulong1: {0,17}", value.Equals(ulong1));
      TestObjectForEquality(ulong1);

      decimal dec1 = 112m;
      Console.WriteLine("value = dec1: {0,21}", value.Equals(dec1));
      TestObjectForEquality(dec1);

      float sng1 = 112;
      Console.WriteLine("value = sng1: {0,19}", value.Equals(sng1));
      TestObjectForEquality(sng1);
   }

   private static void TestObjectForEquality(Object obj)
   {
      Console.WriteLine("{0} ({1}) = {2} ({3}): {4}\n",
                        value, value.GetType().Name,
                        obj, obj.GetType().Name,
                        value.Equals(obj));
   }
}
// The example displays the following output:
//       value = byte1:             True
//       112 (Double) = 112 (Byte): False
//
//       value = short1:             True
//       112 (Double) = 112 (Int16): False
//
//       value = int1:               True
//       112 (Double) = 112 (Int32): False
//
//       value = long1:              True
//       112 (Double) = 112 (Int64): False
//
//       value = sbyte1:             True
//       112 (Double) = 112 (SByte): False
//
//       value = ushort1:             True
//       112 (Double) = 112 (UInt16): False
//
//       value = uint1:               True
//       112 (Double) = 112 (UInt32): False
//
//       value = ulong1:              True
//       112 (Double) = 112 (UInt64): False
//
//       value = dec1:                 False
//       112 (Double) = 112 (Decimal): False
//
//       value = sng1:                True
//       112 (Double) = 112 (Single): False

こちらもご覧ください

適用対象

Equals(Object)

このインスタンスが指定されたオブジェクトに等しいかどうかを示す値を返します。

public:
 override bool Equals(System::Object ^ obj);
public override bool Equals (object obj);
public override bool Equals (object? obj);
override this.Equals : obj -> bool
Public Overrides Function Equals (obj As Object) As Boolean

パラメーター

obj
Object

このインスタンスと比較するオブジェクト。

戻り値

Boolean

objDouble のインスタンスで、このインスタンスの値に等しい場合は true。それ以外の場合は false

注釈

2 つの値の精度が Equals 異なるため、2 つの明らかに同等の値が等しくない可能性があるため、このメソッドは注意して使用する必要があります。 次の例では、 Double 値 .3333 と Double 1 を 3 で除算して返される値が等しくないと報告しています。

// Initialize two doubles with apparently identical values
double double1 = .33333;
object double2 = (double) 1/3;
// Compare them for equality
Console.WriteLine(double1.Equals(double2));    // displays false
// Initialize two doubles with apparently identical values
let double1 = 0.33333
let double2 = double (1 / 3) |> box
// Compare them for equality
printfn $"{double1.Equals double2}"    // displays false
' Initialize two doubles with apparently identical values
Dim double1 As Double = .33333
Dim double2 As Object = 1/3
' Compare them for equality
Console.WriteLine(double1.Equals(double2))    ' displays False

メソッドを呼び出す Equals 代わりに、オーバーロードのドキュメントを Equals(Double) 参照してください。

注意

範囲が 0 に近い正の値の最小式を定義するため Epsilon 、2 つの類似する値の差のマージンは 、より Epsilon大きくする必要があります。 通常、それはより多くの倍大きい Epsilonです。

文書化された有効桁数を超える浮動小数点数の精度は、.NET Frameworkの実装とバージョンに固有です。 その結果、数値の内部表現の精度が変わる可能性があるため、.NET Frameworkのバージョン間で 2 つの特定の数値の比較が変更される可能性があります。

メソッドを呼び出して 2 つの Double.NaN 値が Equals 等しいかどうかをテストすると、メソッドは返します true。 ただし、等値演算子を使用して 2 つの NaN 値が等しいかどうかをテストすると、演算子は返します false。 a Double の値が数値 (NaN) ではないかどうかを判断する場合は、メソッドを呼び出 IsNaN す方法があります。

注意 (呼び出し元)

コンパイラ のオーバーロード解決では、2 つの Equals(Object) メソッド オーバーロードの動作に明らかな違いがある場合があります。 引数と a Double の間のobj暗黙的な変換が定義されていて、引数が型指定Objectされていない場合、コンパイラは暗黙的な変換を実行し、メソッドをEquals(Double)呼び出す可能性があります。 それ以外の場合は、引数がEquals(Object)値でない場合objは常に返されるfalseメソッドをDouble呼び出します。 次の例は、2 つのメソッド オーバーロードの動作の違いを示しています。 C# を除くDecimalすべてのプリミティブ数値型の場合、コンパイラtrueが自動的に拡大変換を実行してメソッドを呼び出すのに対し、コンパイラがメソッドを呼び出Equals(Double)すのに対し、2 番目の比較ではメソッドが呼び出Equals(Object)されるため、最初の比較が返falseされます。

::code language="csharp" source="~/snippets/csharp/System/Double/Equals/equals/equalsoverl.cs" interactive="try-dotnet" id="Snippet2"::: :::code language="fsharp" source="~/snippets/fsharp/System/Double/Equals/equals/equalsoverl.fs" id="Snippet2"::: ::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.double.equals/vb/equalsoverl.vb" id="Snippet2":::

こちらもご覧ください

適用対象