Single.Equals Metoda

Definice

Vrátí hodnotu určující, zda dvě instance Single představují stejnou hodnotu.

Přetížení

Equals(Object)

Vrací hodnotu, která určuje, zda je tato instance rovna zadanému objektu.

Equals(Single)

Vrátí hodnotu určující, zda tato instance a zadaný Single objekt představují stejnou hodnotu.

Equals(Object)

Vrací hodnotu, která určuje, zda je tato instance rovna zadanému objektu.

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

Parametry

obj
Object

Objekt k porovnání s touto instancí.

Návraty

Boolean

true pokud obj je instance a rovná se hodnotě této Single instance; jinak hodnota false .

Příklady

Následující příklad kódu ukazuje Equals metodu .

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

Poznámky

Metoda by se měla používat s opatrností, protože dvě zjevně ekvivalentní hodnoty mohou být nerovné kvůli různé přesnosti Equals těchto dvou hodnot. Následující příklad hlásí, že hodnota .3333 a hodnota vrácená vydělením Single Single hodnoty 1 3 nejsou rovny.

// 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

Jednou z doporučených technik je místo porovnání rovnosti definování přijatelného rozdílového rozpětí mezi dvěma hodnotami (například 0,01 % jedné z hodnot). Pokud je absolutní hodnota rozdílu mezi těmito dvěma hodnotami menší nebo rovna tomtou okraji, rozdíl pravděpodobně bude způsoben rozdíly v přesnosti, a proto se hodnoty budou pravděpodobně rovnat. Následující příklad používá tuto techniku k porovnání 0,3333 a 1/3, dvou hodnot, u které předchozí příklad kódu zjistil, že Single jsou nerovné.

// 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

V tomto případě jsou hodnoty stejné.

Poznámka

Vzhledem k tomu, že definuje minimální výraz kladné hodnoty, jejíž rozsah je blízko nule, musí být rozdílová marže Epsilon větší než Epsilon . Obvykle je mnohem větší než Epsilon .

Přesnost čísel s pohyblivou řádovou čárkou nad rámec dokumentované přesnosti závisí na konkrétní implementaci a verze platformy .NET Framework. Porovnání dvou konkrétních čísel se může následně změnit mezi jednotlivými verzemi platformy .NET Framework, protože může dojít ke změně přesnosti interní reprezentace čísel.

Poznámky pro volající

Rozlišení přetížení kompilátoru může zohlednit zjevný rozdíl v chování dvou Equals(Object) přetížení metody. Pokud je definovaný implicitní převod mezi argumentem a a argument není typován jako , mohou kompilátory provést implicitní převod a zavolat obj Single Object Equals(Single) metodu . V opačném případě volají Equals(Object) metodu , která vždy vrátí hodnotu, pokud false její argument není obj Single hodnota. Následující příklad ukazuje rozdíl v chování mezi těmito dvěma přetíženími metody. V případě všech primitivních číselných typů s výjimkou v jazyce Visual Basic a s výjimkou a v jazyce C# se první porovnání vrátí, protože kompilátor automaticky provádí rozšiřující převod a volá metodu , zatímco druhé porovnání vrátí , protože kompilátor volá Double Decimal Double true Equals(Single) false Equals(Object) metodu .

Viz také

Platí pro

Equals(Single)

Vrátí hodnotu určující, zda tato instance a zadaný Single objekt představují stejnou hodnotu.

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

Parametry

obj
Single

Objekt k porovnání s touto instancí.

Návraty

Boolean

true pokud obj se rovná této instanci, jinak false .

Implementuje

Poznámky

Tato metoda implementuje rozhraní a má trochu lepší výkon než , protože nemusí převést System.IEquatable<T> Equals parametr na obj objekt.

Rozšiřující převody

V závislosti na programovacím jazyce může být možné naprogramovat metodu, ve které má typ parametru méně Equals bitů (je užší) než typ instance. Je to možné, protože některé programovací jazyky provádějí implicitní rozšiřující převod, který představuje parametr jako typ s tolika bity, kolik bitů má instance.

Předpokládejme například, že typ instance je a Single typ parametru je Int32 . Kompilátor jazyka Microsoft C# generuje instrukce, které představují hodnotu parametru jako objekt, a poté vygeneruje metodu, která porovnává hodnoty instance a rozšířenou reprezentaci Single Single.Equals(Single) parametru.

Vyhledejte v dokumentaci k programovacímu jazyku, zda kompilátor provádí implicitní převody pro rozšíření číselných typů. Další informace najdete v tématu Tabulky převodu typů.

Přesnost v porovnávání

Metoda by se měla používat s opatrností, protože dvě zdánlivě ekvivalentní hodnoty mohou být nerovné kvůli různé přesnosti Equals těchto dvou hodnot. Následující příklad hlásí, že hodnota .3333 a hodnota vrácená vydělením Single Single hodnoty 1 3 nejsou rovny.

// 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

Jednou z technik porovnání, která zabraňuje problémům souvisejícím s porovnáním rovnosti, je definování přijatelného rozdílového rozpětí mezi dvěma hodnotami (například 0,01 % jedné z hodnot). Pokud je absolutní hodnota rozdílu mezi těmito dvěma hodnotami menší nebo rovna této marži, rozdíl bude pravděpodobně výsledkem rozdílů v přesnosti, a proto se hodnoty budou pravděpodobně rovnat. Následující příklad používá tuto techniku k porovnání 0,3333 a 1/3, což jsou dvě hodnoty, u kterých předchozí příklad kódu zjistil, že jsou Single nerovné.

// 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

V tomto případě jsou hodnoty stejné.

Poznámka

Vzhledem k tomu, že definuje minimální výraz kladné hodnoty, jejíž rozsah je blízko nule, musí být rozdílová marže Epsilon větší než Epsilon . Obvykle je mnohem větší než Epsilon . Z tohoto důvodu doporučujeme, abyste při porovnávání hodnot pro rovnost Epsilon Double nepoučovali .

Druhá technika, která zabraňuje problémům souvisejícím s porovnáváním rovnosti, zahrnuje porovnání rozdílu mezi dvěma čísly s plovoucí desetinnou čárkou a absolutní hodnotou. Pokud je rozdíl menší nebo roven této absolutní hodnotě, jsou čísla rovna. Pokud je větší, čísla nejsou rovna. Jedním ze způsobů, jak to provést, je libovolně vybrat absolutní hodnotu. To je ale problematické, protože přijatelné rozpětí rozdílu závisí na velikosti Single hodnot. Druhý způsob využívá funkci návrhu ve formátu s plovoucí desetinnou čárkou: Rozdíl mezi komponentami manissa v celočíselných reprezentacích dvou hodnot s plovoucí desetinnou čárkou označuje počet možných hodnot s plovoucí desetinnou čárkou, které tyto dvě hodnoty oddělí. Například rozdíl mezi 0,0 a je 1, protože je nejmenší reprezentovatelná hodnota při práci s hodnotou, jejíž hodnota Epsilon Epsilon je Single nula. Následující příklad používá tuto techniku k porovnání 0,3333 a 1/3, což jsou dvě hodnoty, které předchozí příklad kódu s metodou zjistil, že Double Equals(Single) jsou nerovné. Všimněte si, že příklad používá metody a k převodu hodnoty s plovoucí desetinnou čárkou s přesností BitConverter.GetBytes BitConverter.ToInt32 na celočíselnou reprezentaci.

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

Přesnost čísel s pohyblivou řádovou čárkou nad rámec dokumentované přesnosti závisí na konkrétní implementaci a verze platformy .NET Framework. V důsledku toho může porovnání dvou čísel v závislosti na verzi .NET Framework, protože přesnost interní reprezentace čísel se může změnit.

Poznámky pro volající

Rozlišení přetížení kompilátoru může zohlednit zjevný rozdíl v chování dvou Equals(Object) přetížení metody. Pokud je definovaný implicitní převod mezi argumentem a a argument není typován jako , mohou kompilátory provést implicitní převod a zavolat obj Single Object Equals(Single) metodu . V opačném případě volají Equals(Object) metodu , která vždy vrátí hodnotu, pokud false její argument není obj Single hodnota. Následující příklad ukazuje rozdíl v chování mezi těmito dvěma přetíženími metody. V případě všech primitivních číselných typů s výjimkou v jazyce Visual Basic a s výjimkou a v jazyce C# se první porovnání vrátí, protože kompilátor automaticky provádí rozšiřující převod a volá metodu , zatímco druhé porovnání vrátí , protože kompilátor volá Double Decimal Double true Equals(Single) false Equals(Object) metodu .

Viz také

Platí pro