Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Uyarı
Bu makale, bu API'nin başvuru belgelerine ek açıklamalar sağlar.
Single.Equals(Single) yöntemi, System.IEquatable<T> arabirimini uygular ve Single.Equals(Object) parametresini bir nesneye dönüştürmesi gerekmediğinden obj ile karşılaştırıldığında biraz daha iyi performans gösterir.
Genişleyen dönüşümler
Programlama dilinize bağlı olarak, parametre türünün örnek türünden daha az bit (daha dar) olduğu bir Equals yöntem kodlayabilirsiniz. Bunun nedeni, bazı programlama dillerinin parametreyi örnek kadar bit içeren bir tür olarak temsil eden örtük bir genişletme dönüştürmesi gerçekleştirmesi olabilir.
Örneğin, örnek türünün Single ve parametre türünün Int32olduğunu varsayalım. Microsoft C# derleyicisi parametrenin değerini nesne Single olarak temsil eden yönergeler oluşturur ve ardından örneğin değerlerini ve parametrenin geniş gösterimini karşılaştıran bir Single.Equals(Single) yöntem oluşturur.
Derleyicisinin sayısal türlerde örtük genişletme dönüştürmeleri gerçekleştirip gerçekleştirmediğini belirlemek için programlama dilinizin belgelerine bakın. Daha fazla bilgi için bkz. Tür Dönüştürme Tabloları.
Karşılaştırmalarda kesinlik
Equals yöntemi dikkatli bir şekilde kullanılmalıdır, çünkü görünüşte eşdeğer olan iki değer, farklı duyarlıklara sahip olmaları nedeniyle eşit olmayabilir. Aşağıdaki örnek, Single değerinin .3333 olduğunu ve 1'in 3'e bölünmesiyle elde edilen Single değerinin eşit olmadığını bildirir.
// 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 floats with apparently identical values
let float1 = 0.33333f
let float2 = 1f / 3f
// Compare them for equality
printfn $"{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
Eşitlik karşılaştırmasıyla ilgili sorunlardan kaçınan bir karşılaştırma tekniği, iki değer arasında kabul edilebilir bir fark marjı tanımlamayı içerir (örneğin, değerlerden birinin 0,01%). İki değer arasındaki farkın mutlak değeri bu kenar boşluğundan küçük veya buna eşitse, fark büyük olasılıkla duyarlık farklılıklarının sonucudur ve bu nedenle değerlerin eşit olması muhtemeldir. Aşağıdaki örnek, önceki kod örneğinin eşit olmadığını bulduğu iki Single değer olan .33333 ve 1/3'leri karşılaştırmak için bu tekniği kullanır.
// 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 floats with apparently identical values
let float1 = 0.33333f
let float2 = 1f / 3f
// Define the tolerance for variation in their values
let difference = abs (float1 * 0.0001f)
// Compare the values
// The output to the console indicates that the two values are equal
if abs (float1 - float2) <= difference then
printfn "float1 and float2 are equal."
else
printfn "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
Bu durumda değerler eşittir.
Uyarı
Aralığı sıfıra yakın olan pozitif bir değerin minimum ifadesini tanımladığından Epsilon , farkın kenar boşluğu değerinden Epsilonbüyük olmalıdır. Genellikle, değerinden çok daha Epsilonbüyüktür. Bu nedenle, Epsilon değerlerini eşitlik için karşılaştırırken Double kullanmamanızı öneririz.
Eşitlik karşılaştırmasıyla ilgili sorunlardan kaçınan ikinci bir teknik, iki kayan noktalı sayı arasındaki farkın mutlak bir değerle karşılaştırılmasını içerir. Fark bu mutlak değerden küçük veya buna eşitse, sayılar eşittir. Daha büyükse, sayılar eşit değildir. Bunu yapmanızın bir yolu, rastgele bir mutlak değer seçmektir. Ancak, kabul edilebilir bir fark marjı değerlerin büyüklüğüne Single bağlı olduğundan bu sorun yaratır. İkinci bir yol kayan nokta biçiminin tasarım özelliğinden yararlanır: İki kayan nokta değerinin tamsayı gösterimlerindeki mantis bileşenleri arasındaki fark, iki değeri ayıran olası kayan nokta değerlerinin sayısını gösterir. Örneğin, 0,0 ile Epsilon 1 arasındaki farktır, çünkü Epsilon değeri sıfır olan bir Single değerle çalışırken en küçük temsil edilebilir değerdir. Aşağıdaki örnek, önceki kod örneğinin yöntemle eşit olmadığını bulduğu iki Double değer olan .33333 ve Equals(Single) 1/3'leri karşılaştırmak için bu tekniği kullanır. Örneğin, tek duyarlıklı kayan nokta değerini tamsayı gösterimine dönüştürmek için BitConverter.GetBytes ve BitConverter.ToInt32 yöntemlerini kullandığını unutmayın.
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($"{value1:R} = {value2:R}: {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
open System
let hasMinimalDifference (value1: float32) (value2: float32) units =
let bytes = BitConverter.GetBytes value1
let iValue1 = BitConverter.ToInt32(bytes, 0)
let bytes = BitConverter.GetBytes(value2)
let iValue2 = BitConverter.ToInt32(bytes, 0)
// If the signs are different, return false except for +0 and -0.
if (iValue1 >>> 31) <> (iValue2 >>> 31) then
value1 = value2
else
let diff = abs (iValue1 - iValue2)
diff <= units
let value1 = 0.1f * 10f
let value2 =
List.replicate 10 0.1f
|> List.sum
printfn $"{value1:R} = {value2:R}: {hasMinimalDifference value1 value2 1}"
// The example displays the following output:
// 1 = 1.0000001: 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
Kayan noktalı sayıların, belgelenen duyarlığı aşan duyarlığı, .NET'in uygulamasına ve sürümüne özgüdür. Sonuç olarak, iki sayının karşılaştırması .NET sürümüne bağlı olarak farklı sonuçlar verebilir, çünkü sayıların iç gösteriminin duyarlığı değişebilir.