Single.Equals メソッド

定義

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

オーバーロード

Equals(Object)

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

Equals(Single)

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

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

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

次のコード例は、 メソッドを示 Equals しています。

obj1 = (Single)500;

if ( a.Equals( obj1 ) )
{
   Console::WriteLine( "The value type and reference type values are equal." );
}
obj1 = (Single)500;
if (a.Equals(obj1)) {
    Console.WriteLine("The value type and reference type values are equal.");
}
Obj1 = CType(500, Single)

If A.Equals(Obj1) Then
    Console.WriteLine("The value type and reference type values are equal.")
End If

注釈

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

// Initialize two floats with apparently identical values
float float1 = .33333f;
object float2 = 1/3;
// Compare them for equality
Console.WriteLine(float1.Equals(float2));    // displays false
' Initialize two singles with apparently identical values
Dim single1 As Single = .33333
Dim single2 As Object = 1/3
' Compare them for equality
Console.WriteLine(single1.Equals(single2))    ' displays False

1 つの推奨される手法では、等値を比較するのではなく、2 つの値 (値の 1 つの .01% など) の差の許容される余白を定義する必要があります。 2 つの値の差の絶対値が、その余白以下の場合、その差は精度の違いによる可能性が高く、したがって、値が等しくなります。 次の例では、この手法を使用して、前のコード例で見つかった 2 つの値である .33333 と 1/3 Single を比較します。

// Initialize two floats with apparently identical values
float float1 = .33333f;
object float2 = (float) 1/3;
// Define the tolerance for variation in their values
float difference = Math.Abs(float1 * .0001f);

// Compare the values
// The output to the console indicates that the two values are equal
if (Math.Abs(float1 - (float) float2) <= difference)
   Console.WriteLine("float1 and float2 are equal.");
else
   Console.WriteLine("float1 and float2 are unequal.");
' Initialize two singles with apparently identical values
Dim single1 As Single = .33333
Dim single2 As Object = 1/3
' Define the tolerance for variation in their values
Dim difference As Single = Math.Abs(single1 * .0001f)

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

この場合、値は等しくなります。

注意

は範囲が 0 に近い正の値の最小式を定義します。ため、差の余白は より Epsilon 大きくする必要があります Epsilon 。 通常は、 よりも何倍も大きくなります Epsilon

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

注意 (呼び出し元)

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

using System;

public class Example
{
   static float 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);

      double dbl1 = 112;
      Console.WriteLine("value = dbl1: {0,20}", value.Equals(dbl1));
      TestObjectForEquality(dbl1);
   }

   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 (Single) = 112 (Byte): False
//
//       value = short1:             True
//       112 (Single) = 112 (Int16): False
//
//       value = int1:               True
//       112 (Single) = 112 (Int32): False
//
//       value = long1:              True
//       112 (Single) = 112 (Int64): False
//
//       value = sbyte1:             True
//       112 (Single) = 112 (SByte): False
//
//       value = ushort1:             True
//       112 (Single) = 112 (UInt16): False
//
//       value = uint1:               True
//       112 (Single) = 112 (UInt32): False
//
//       value = ulong1:              True
//       112 (Single) = 112 (UInt64): False
//
//       value = dec1:                 False
//       112 (Single) = 112 (Decimal): False
//
//       value = dbl1:                False
//       112 (Single) = 112 (Double): False

こちらもご覧ください

適用対象

Equals(Single)

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

public:
 virtual bool Equals(float obj);
public bool Equals (float obj);
override this.Equals : single -> bool
Public Function Equals (obj As Single) As Boolean

パラメーター

obj
Single

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

戻り値

Boolean

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

実装

注釈

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

拡大変換

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

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

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

比較における精度

2つ Equals の値の有効桁数が異なるため、2つの意味のある値は等しくない可能性があるため、このメソッドは注意して使用する必要があります。 次の例では、 Single Single 1 を3で割ることによって返された3333との値が等しくないことを報告しています。

// Initialize two floats with apparently identical values
float float1 = .33333f;
float float2 = 1/3;
// Compare them for equality
Console.WriteLine(float1.Equals(float2));    // displays false
' Initialize two singles with apparently identical values
Dim single1 As Single = .33333
Dim single2 As Single = 1/3
' Compare them for equality
Console.WriteLine(single1.Equals(single2))    ' displays False

等しいかどうかの比較に関連する問題を回避する比較手法の1つは、2つの値の差に許容される余白を定義することです (1 つの値の0.01% など)。 2つの値の差の絶対値がその余白以下である場合、相違点は精度の差の結果である可能性が高いため、値が等しい可能性があります。 次の例では、この手法を使用して、33333と1/3 を比較しています。これは、 Single 前のコード例の2つの値が等しくないことを示しています。

// Initialize two floats with apparently identical values
float float1 = .33333f;
float float2 = (float) 1/3;
// Define the tolerance for variation in their values
float difference = Math.Abs(float1 * .0001f);

// Compare the values
// The output to the console indicates that the two values are equal
if (Math.Abs(float1 - float2) <= difference)
   Console.WriteLine("float1 and float2 are equal.");
else
   Console.WriteLine("float1 and float2 are unequal.");
' Initialize two singles with apparently identical values
Dim single1 As Single = .33333
Dim single2 As Single = 1/3
' Define the tolerance for variation in their values
Dim difference As Single = Math.Abs(single1 * .0001f)

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

この場合、値は等しいと見なされます。

注意

Epsilonは、範囲がゼロ付近の正の値の最小式を定義するため、差の余白はよりも大きくする必要があり Epsilon ます。 通常、よりも多くの時間がかかり Epsilon ます。 このため、 Epsilon 値が等しいかどうかを比較する場合は、を使用しないことをお勧め Double します。

等しいかどうかの比較に関連する問題を回避する2番目の手法では、2つの浮動小数点数の差を絶対値で比較します。 差分値がその絶対値以下の場合、数値は等しいと見なされます。 値が大きい場合、数値は等しくありません。 これを行う1つの方法として、絶対値を任意に選択する方法があります。 ただし、これは問題になります。これは、許容される差の余白が値の大きさに依存するためです Single 。 2番目の方法では、浮動小数点形式のデザイン機能を利用します。2つの浮動小数点値の整数表現に含まれる仮数部分の差は、2つの値を区切る可能性のある浮動小数点値の数を示します。 たとえば、の Epsilon Epsilon 値が0のを操作する場合、が最も小さい表現可能な値であるため、0.0 との差は1になり Single ます。 次の例では、この手法を使用して、33333と1/3 を比較しています。これは、 Double 前のコード例では、 Equals(Single) メソッドが等しくないと判明した2つの値です。 この例では、メソッドとメソッドを使用して、 BitConverter.GetBytes BitConverter.ToInt32 単精度浮動小数点値を整数表現に変換します。

using System;

public class Example
{
   public static void Main()
   {
      float value1 = .1f * 10f;
      float value2 = 0f;
      for (int ctr = 0; ctr < 10; ctr++)
         value2 += .1f;
         
      Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2,
                        HasMinimalDifference(value1, value2, 1));
   }

   public static bool HasMinimalDifference(float value1, float value2, int units)
   {
      byte[] bytes = BitConverter.GetBytes(value1);
      int iValue1 = BitConverter.ToInt32(bytes, 0);
      
      bytes = BitConverter.GetBytes(value2);
      int iValue2 = BitConverter.ToInt32(bytes, 0);
      
      // If the signs are different, return false except for +0 and -0.
      if ((iValue1 >> 31) != (iValue2 >> 31))
      {
         if (value1 == value2)
            return true;
          
         return false;
      }

      int diff = Math.Abs(iValue1 - iValue2);

      if (diff <= units)
         return true;

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

   Public Function HasMinimalDifference(value1 As Single, value2 As Single, units As Integer) As Boolean
      Dim bytes() As Byte = BitConverter.GetBytes(value1)
      Dim iValue1 As Integer =  BitConverter.ToInt32(bytes, 0)
      
      bytes = BitConverter.GetBytes(value2)
      Dim iValue2 As Integer =  BitConverter.ToInt32(bytes, 0)
      
      ' If the signs are different, Return False except for +0 and -0.
      If ((iValue1 >> 31) <> (iValue2 >> 31)) Then
         If value1 = value2 Then
            Return True
         End If           
         Return False
      End If

      Dim diff As Integer =  Math.Abs(iValue1 - iValue2)

      If diff <= units Then
         Return True
      End If

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

ドキュメント化された有効桁数を超える浮動小数点数の有効桁数は、.NET Framework の実装とバージョンに固有です。 このため、2つの数値を比較すると、.NET Framework のバージョンによって異なる結果が生成される可能性があります。これは、数値の内部表現の有効桁数が変更される可能性があるためです。

注意 (呼び出し元)

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

using System;

public class Example
{
   static float 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);

      double dbl1 = 112;
      Console.WriteLine("value = dbl1: {0,20}", value.Equals(dbl1));
      TestObjectForEquality(dbl1);
   }

   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 (Single) = 112 (Byte): False
//
//       value = short1:             True
//       112 (Single) = 112 (Int16): False
//
//       value = int1:               True
//       112 (Single) = 112 (Int32): False
//
//       value = long1:              True
//       112 (Single) = 112 (Int64): False
//
//       value = sbyte1:             True
//       112 (Single) = 112 (SByte): False
//
//       value = ushort1:             True
//       112 (Single) = 112 (UInt16): False
//
//       value = uint1:               True
//       112 (Single) = 112 (UInt32): False
//
//       value = ulong1:              True
//       112 (Single) = 112 (UInt64): False
//
//       value = dec1:                 False
//       112 (Single) = 112 (Decimal): False
//
//       value = dbl1:                False
//       112 (Single) = 112 (Double): False

こちらもご覧ください

適用対象