Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo fornece comentários complementares à documentação de referência para esta API.
O valor da Epsilon propriedade reflete o menor valor positivo Double que é significativo em operações numéricas ou comparações quando o valor da Double instância é zero. Por exemplo, o código a seguir mostra que zero e Epsilon são considerados valores desiguais, enquanto zero e metade do valor são Epsilon considerados iguais.
using System;
public class Example
{
public static void Main()
{
double[] values = { 0, Double.Epsilon, Double.Epsilon * .5 };
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 = 4.94065645841247E-324: False
// 0 = 0: True
//
// 4.94065645841247E-324 = 0: False
open System
let values = [| 0.; Double.Epsilon; Double.Epsilon * 0.5 |]
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 = 4.94065645841247E-324: False
// 0 = 0: True
//
// 4.94065645841247E-324 = 0: False
Module Example
Public Sub Main()
Dim values() As Double = { 0, Double.Epsilon, Double.Epsilon * .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 = 4.94065645841247E-324: False
' 0 = 0: True
'
' 4.94065645841247E-324 = 0: False
Mais precisamente, o formato de ponto flutuante consiste em um sinal, um significando ou uma mantissa de 52 bits e um expoente de 11 bits. Como mostra o exemplo a seguir, zero tem um expoente de -1022 e uma mantissa de 0. Epsilon tem um expoente de -1022 e uma mantissa de 1. Isso significa que esse Epsilon é o menor valor positivo Double maior que zero e representa o menor valor possível e o menor incremento possível para um Double cujo expoente é -1022.
using System;
public class Example1
{
public static void Main()
{
double[] values = { 0.0, Double.Epsilon };
foreach (var value in values)
{
Console.WriteLine(GetComponentParts(value));
Console.WriteLine();
}
}
private static string GetComponentParts(double value)
{
string result = String.Format("{0:R}: ", value);
int indent = result.Length;
// Convert the double to an 8-byte array.
byte[] bytes = BitConverter.GetBytes(value);
// Get the sign bit (byte 7, bit 7).
result += String.Format("Sign: {0}\n",
(bytes[7] & 0x80) == 0x80 ? "1 (-)" : "0 (+)");
// Get the exponent (byte 6 bits 4-7 to byte 7, bits 0-6)
int exponent = (bytes[7] & 0x07F) << 4;
exponent = exponent | ((bytes[6] & 0xF0) >> 4);
int adjustment = exponent != 0 ? 1023 : 1022;
result += String.Format("{0}Exponent: 0x{1:X4} ({1})\n", new String(' ', indent), exponent - adjustment);
// Get the significand (bits 0-51)
long significand = ((bytes[6] & 0x0F) << 48);
significand = significand | ((long)bytes[5] << 40);
significand = significand | ((long)bytes[4] << 32);
significand = significand | ((long)bytes[3] << 24);
significand = significand | ((long)bytes[2] << 16);
significand = significand | ((long)bytes[1] << 8);
significand = significand | bytes[0];
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: 0xFFFFFC02 (-1022)
// Mantissa: 0x0000000000000
//
//
// 4.94065645841247E-324: Sign: 0 (+)
// Exponent: 0xFFFFFC02 (-1022)
// Mantissa: 0x0000000000001
open System
let getComponentParts (value: double) =
let result = $"{value:R}: "
let indent = result.Length
// Convert the double to an 8-byte array.
let bytes = BitConverter.GetBytes value
// Get the sign bit (byte 7, bit 7).
let result = result + $"""Sign: {if (bytes[7] &&& 0x80uy) = 0x80uy then "1 (-)" else "0 (+)"}\n"""
// Get the exponent (byte 6 bits 4-7 to byte 7, bits 0-6)
let exponent = (bytes[7] &&& 0x07Fuy) <<< 4
let exponent = exponent ||| ((bytes[6] &&& 0xF0uy) >>> 4)
let adjustment = if exponent <> 0uy then 1022 else 1023
let result = result + $"{String(' ', indent)}Exponent: 0x{int exponent - adjustment:X4} ({int exponent - adjustment})\n"
// Get the significand (bits 0-51)
let significand = (bytes[6] &&& 0x0Fuy) <<< 48
let significand = significand ||| byte (int64 bytes[5] <<< 40)
let significand = significand ||| byte (int64 bytes[4] <<< 32)
let significand = significand ||| byte (int64 bytes[3] <<< 24)
let significand = significand ||| byte (int64 bytes[2] <<< 16)
let significand = significand ||| byte (int64 bytes[1] <<< 8)
let significand = significand ||| bytes[0]
result + $"{String(' ', indent)}Mantissa: 0x{significand:X13}\n"
let values = [| 0.; Double.Epsilon |]
for value in values do
printfn $"{getComponentParts value}"
printfn ""
// // The example displays the following output:
// 0: Sign: 0 (+)
// Exponent: 0xFFFFFC02 (-1022)
// Mantissa: 0x0000000000000
//
//
// 4.94065645841247E-324: Sign: 0 (+)
// Exponent: 0xFFFFFC02 (-1022)
// Mantissa: 0x0000000000001
Module Example1
Public Sub Main()
Dim values() As Double = { 0.0, Double.Epsilon }
For Each value In values
Console.WriteLine(GetComponentParts(value))
Console.WriteLine()
Next
End Sub
Private Function GetComponentParts(value As Double) As String
Dim result As String = String.Format("{0:R}: ", value)
Dim indent As Integer = result.Length
' Convert the double to an 8-byte array.
Dim bytes() As Byte = BitConverter.GetBytes(value)
' Get the sign bit (byte 7, bit 7).
result += String.Format("Sign: {0}{1}",
If((bytes(7) And &H80) = &H80, "1 (-)", "0 (+)"),
vbCrLf)
' Get the exponent (byte 6 bits 4-7 to byte 7, bits 0-6)
Dim exponent As Integer = (bytes(7) And &H07F) << 4
exponent = exponent Or ((bytes(6) And &HF0) >> 4)
Dim adjustment As Integer = If(exponent <> 0, 1023, 1022)
result += String.Format("{0}Exponent: 0x{1:X4} ({1}){2}",
New String(" "c, indent), exponent - adjustment,
vbCrLf)
' Get the significand (bits 0-51)
Dim significand As Long = ((bytes(6) And &H0F) << 48)
significand = significand Or (bytes(5) << 40)
significand = significand Or (bytes(4) << 32)
significand = significand Or (bytes(3) << 24)
significand = significand Or (bytes(2) << 16)
significand = significand Or (bytes(1) << 8)
significand = significand Or bytes(0)
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: 0xFFFFFC02 (-1022)
' Mantissa: 0x0000000000000
'
'
' 4.94065645841247E-324: Sign: 0 (+)
' Exponent: 0xFFFFFC02 (-1022)
' Mantissa: 0x0000000000001
No entanto, a Epsilon propriedade não é uma medida geral de precisão do Double tipo; ela se aplica apenas a Double instâncias que têm um valor igual a zero ou um expoente de -1022.
Observação
O valor da Epsilon propriedade não é equivalente ao epsilon do computador, que representa o limite superior do erro relativo devido ao arredondamento em aritmética de ponto flutuante.
O valor dessa constante é 4.94065645841247e-324.
Dois números de ponto flutuante aparentemente equivalentes podem não ser considerados iguais devido a diferenças em seus dígitos menos relevantes. Por exemplo, a expressão (double)1/3 == (double)0.33333 em C# não é considerada igual porque a operação de divisão no lado esquerdo apresenta precisão máxima, enquanto a constante no lado direito é precisa apenas em relação aos dígitos especificados. Se você criar um algoritmo personalizado que determine se dois números de ponto flutuante podem ser considerados iguais, não recomendamos que você baseie seu algoritmo no valor da Epsilon constante para estabelecer a margem absoluta aceitável de diferença para que os dois valores sejam considerados iguais. (Normalmente, essa margem de diferença é muitas vezes maior que Epsilon.) Para obter informações sobre como comparar dois valores de ponto flutuante de precisão dupla, consulte Double e Equals(Double).
Notas da plataforma
Em sistemas ARM, o valor da Epsilon constante é muito pequeno para ser detectado, portanto, equivale a zero. Você pode definir um valor epsilon alternativo igual a 2,2250738585072014E-308.