Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek obsahuje doplňující poznámky k referenční dokumentaci pro toto rozhraní API.
Hodnota vlastnosti Epsilon odráží nejmenší kladnou Single hodnotu, která je významná v numerických operacích nebo porovnání, pokud je hodnota Single instance nula. Následující kód například ukazuje, že nula a Epsilon jsou považovány za nerovné hodnoty, zatímco nula a polovina hodnoty Epsilon se považují za rovnou.
using System;
public class Example1
{
public static void Main()
{
float[] values = { 0f, Single.Epsilon, Single.Epsilon * .5f };
for (int ctr = 0; ctr <= values.Length - 2; ctr++)
{
for (int ctr2 = ctr + 1; ctr2 <= values.Length - 1; ctr2++)
{
Console.WriteLine($"{values[ctr]:r} = {values[ctr2]:r}: {values[ctr].Equals(values[ctr2])}");
}
Console.WriteLine();
}
}
}
// The example displays the following output:
// 0 = 1.401298E-45: False
// 0 = 0: True
//
// 1.401298E-45 = 0: False
open System
let values = [ 0f; Single.Epsilon; Single.Epsilon * 0.5f ]
for i = 0 to values.Length - 2 do
for i2 = i + 1 to values.Length - 1 do
printfn $"{values[i]:r} = {values[i2]:r}: {values[i].Equals(values[i2])}"
printfn ""
// The example displays the following output:
// 0 = 1.401298E-45: False
// 0 = 0: True
//
// 1.401298E-45 = 0: False
Module Example1
Public Sub Main()
Dim values() As Single = {0, Single.Epsilon, Single.Epsilon * 0.5}
For ctr As Integer = 0 To values.Length - 2
For ctr2 As Integer = ctr + 1 To values.Length - 1
Console.WriteLine("{0:r} = {1:r}: {2}",
values(ctr), values(ctr2),
values(ctr).Equals(values(ctr2)))
Next
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' 0 = 1.401298E-45: False
' 0 = 0: True
'
' 1.401298E-45 = 0: False
Přesněji řečeno, formát plovoucí desetinné čárky s jednoduchou přesností se skládá ze znaménka, 23bitové mantisy nebo významové části a 8bitového exponentu. Jak ukazuje následující příklad, nula má exponent -126 a mantisu 0. Epsilon má exponent -126 a mantisu rovnu 1. To znamená, že Single.Epsilon je nejmenší kladná Single hodnota větší než nula a představuje nejmenší možnou hodnotu a nejmenší možný přírůstek pro Single, jehož exponent je -126.
using System;
public class Example2
{
public static void Main()
{
float[] values = { 0.0f, Single.Epsilon };
foreach (var value in values) {
Console.WriteLine(GetComponentParts(value));
Console.WriteLine();
}
}
private static string GetComponentParts(float value)
{
string result = String.Format("{0:R}: ", value);
int indent = result.Length;
// Convert the single to a 4-byte array.
byte[] bytes = BitConverter.GetBytes(value);
int formattedSingle = BitConverter.ToInt32(bytes, 0);
// Get the sign bit (byte 3, bit 7).
result += String.Format("Sign: {0}\n",
(formattedSingle >> 31) != 0 ? "1 (-)" : "0 (+)");
// Get the exponent (byte 2 bit 7 to byte 3, bits 6)
int exponent = (formattedSingle >> 23) & 0x000000FF;
int adjustment = (exponent != 0) ? 127 : 126;
result += String.Format("{0}Exponent: 0x{1:X4} ({1})\n", new String(' ', indent), exponent - adjustment);
// Get the significand (bits 0-22)
long significand = exponent != 0 ?
((formattedSingle & 0x007FFFFF) | 0x800000) :
(formattedSingle & 0x007FFFFF);
result += String.Format("{0}Mantissa: 0x{1:X13}\n", new String(' ', indent), significand);
return result;
}
}
// // The example displays the following output:
// 0: Sign: 0 (+)
// Exponent: 0xFFFFFF82 (-126)
// Mantissa: 0x0000000000000
//
//
// 1.401298E-45: Sign: 0 (+)
// Exponent: 0xFFFFFF82 (-126)
// Mantissa: 0x0000000000001
open System
let getComponentParts (value: float32) =
let result = $"{value:R}: "
let indent = result.Length
// Convert the single to a 4-byte array.
let bytes = BitConverter.GetBytes value
let formattedSingle = BitConverter.ToInt32(bytes, 0)
// Get the sign bit (byte 3, bit 7).
let result = result + $"""Sign: {if formattedSingle >>> 31 <> 0 then "1 (-)" else "0 (+)"}\n"""
// Get the exponent (byte 2 bit 7 to byte 3, bits 6)
let exponent = (formattedSingle >>> 23) &&& 0x000000FF
let adjustment = if exponent <> 0 then 127 else 126
let result = result + $"{String(' ', indent)}Exponent: 0x{1:X4} ({exponent - adjustment})\n"
// Get the significand (bits 0-22)
let significand =
if exponent <> 0 then
(formattedSingle &&& 0x007FFFFF) ||| 0x800000
else
formattedSingle &&& 0x007FFFFF
result + $"{String(' ', indent)}Mantissa: 0x{significand:X13}\n"
let values = [ 0f; Single.Epsilon ]
for value in values do
printfn $"{getComponentParts value}\n"
// // The example displays the following output:
// 0: Sign: 0 (+)
// Exponent: 0xFFFFFF82 (-126)
// Mantissa: 0x0000000000000
//
//
// 1.401298E-45: Sign: 0 (+)
// Exponent: 0xFFFFFF82 (-126)
// Mantissa: 0x0000000000001
Module Example2
Public Sub Main()
Dim values() As Single = {0.0, Single.Epsilon}
For Each value In values
Console.WriteLine(GetComponentParts(value))
Console.WriteLine()
Next
End Sub
Private Function GetComponentParts(value As Single) As String
Dim result As String = String.Format("{0:R}: ", value)
Dim indent As Integer = result.Length
' Convert the single to an 8-byte array.
Dim bytes() As Byte = BitConverter.GetBytes(value)
Dim formattedSingle As Integer = BitConverter.ToInt32(bytes, 0)
' Get the sign bit (byte 3, bit 7).
result += String.Format("Sign: {0}{1}",
If(formattedSingle >> 31 <> 0, "1 (-)", "0 (+)"),
vbCrLf)
' Get the exponent (byte 2 bit 7 to byte 3, bits 6)
Dim exponent As Integer = (formattedSingle >> 23) And &HFF
Dim adjustment As Integer = If(exponent <> 0, 127, 126)
result += String.Format("{0}Exponent: 0x{1:X4} ({1}){2}",
New String(" "c, indent), exponent - adjustment,
vbCrLf)
' Get the significand (bits 0-22)
Dim significand As Long = If(exponent <> 0,
(formattedSingle And &H7FFFFF) Or &H800000,
formattedSingle And &H7FFFFF)
result += String.Format("{0}Mantissa: 0x{1:X13}{2}",
New String(" "c, indent), significand, vbCrLf)
Return result
End Function
End Module
' The example displays the following output:
' 0: Sign: 0 (+)
' Exponent: 0xFFFFFF82 (-126)
' Mantissa: 0x0000000000000
'
'
' 1.401298E-45: Sign: 0 (+)
' Exponent: 0xFFFFFF82 (-126)
' Mantissa: 0x0000000000001
Vlastnost Epsilon však není obecnou mírou přesnosti typu Single; platí pouze pro Single instance, které mají hodnotu nula.
Poznámka:
Hodnota vlastnosti Epsilon není ekvivalentní strojovému epsilonu, který představuje horní mez relativní chyby způsobené zaokrouhlením v aritmetice s pohyblivou řádovou čárkou.
Hodnota této konstanty je 1,4e-45.
Dvě zdánlivě ekvivalentní čísla s plovoucí desetinou čárkou nemusí být považována za stejná kvůli rozdílům v jejich nejméně významných číslicích. Například výraz C# (float)1/3 == (float)0.33333
se nerovná, protože operace dělení na levé straně má maximální přesnost, zatímco konstanta na pravé straně je přesná pouze na specifikované číslice. Pokud vytvoříte vlastní algoritmus, který určuje, zda lze dvě čísla s plovoucí desetinnou čárkou považovat za stejná, musíte použít hodnotu větší než konstanta Epsilon, aby se určila přijatelná absolutní odchylka mezi těmito hodnotami, které mají být považovány za stejné. (Tento rozdíl je obvykle mnohokrát větší než Epsilon.)
Poznámky k platformě
V systémech ARM je hodnota Epsilon konstanty příliš malá, aby se zjistila, takže se rovná nule. Můžete definovat alternativní hodnotu epsilon, která se rovná 1,175494351E-38.