Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Opmerking
In dit artikel vindt u aanvullende opmerkingen in de referentiedocumentatie voor deze API.
De waarde van de Epsilon eigenschap weerspiegelt de kleinste positieve Single waarde die significant is in numerieke bewerkingen of vergelijkingen wanneer de waarde van het Single exemplaar nul is. De volgende code laat bijvoorbeeld zien dat nul en Epsilon als ongelijke waarden worden beschouwd, terwijl nul en de helft van Epsilon de waarde als gelijk worden beschouwd.
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
Precies gezegd, de drijvende-komma-indeling met enkelvoudige precisie bestaat uit een teken, een 23-bits mantissa of significand, en een 8-bits exponent. Zoals in het volgende voorbeeld wordt weergegeven, heeft nul een exponent van -126 en een mantissa van 0. Epsilon heeft een exponent van -126 en een mantissa van 1. Dit betekent dat Single.Epsilon dit de kleinste positieve Single waarde is die groter is dan nul en de kleinste mogelijke waarde vertegenwoordigt en de kleinste mogelijke verhoging voor een Single wiens exponent -126 is.
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
De Epsilon eigenschap is echter geen algemene meting van precisie van het Single type. Deze eigenschap is alleen Single van toepassing op exemplaren met een waarde van nul.
Opmerking
De waarde van de Epsilon eigenschap is niet gelijk aan machine epsilon, die de bovengrens van de relatieve fout representeert door afronding in drijvende-kommarekenkunde.
De waarde van deze constante is 1,4e-45.
Twee schijnbaar equivalente drijvendekommanummers kunnen mogelijk niet als gelijk worden beschouwd door verschillen in hun minst significante cijfers. De C#-expressie, bijvoorbeeld, (float)1/3 == (float)0.33333vergelijkt niet gelijk omdat de verdelingsbewerking aan de linkerkant maximale precisie heeft, terwijl de constante aan de rechterkant alleen precies is voor de opgegeven cijfers. Als u een aangepast algoritme maakt waarmee wordt bepaald of twee drijvendekommanummers als gelijk kunnen worden beschouwd, moet u een waarde gebruiken die groter is dan de Epsilon constante om de acceptabele absolute marge van het verschil vast te stellen voor de twee waarden die als gelijk moeten worden beschouwd. (Normaal gesproken is die marge van verschil vaak groter dan Epsilon.)
Platformnotities
In ARM-systemen is de waarde van de Epsilon constante te klein om te worden gedetecteerd, zodat deze gelijk is aan nul. U kunt een alternatieve epsilon-waarde definiƫren die gelijk is aan 1,175494351E-38.