System.Single.Epsilon 속성
이 문서에서는 이 API에 대한 참조 설명서에 대한 추가 설명서를 제공합니다.
속성 값은 인스턴스 값 Epsilon 이 0일 때 숫자 연산 또는 비교에서 중요한 가장 작은 양의 Single 값을 Single 반영합니다. 예를 들어 다음 코드는 0이고 Epsilon 같지 않은 값으로 간주되는 반면 값의 Epsilon 0과 절반은 같은 것으로 간주됩니다.
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("{0:r} = {1:r}: {2}",
values[ctr], values[ctr2],
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
보다 정확하게 말하자면, 단정밀도 부동 소수점 형식은 부호, 23비트 매니티사 또는 유의성 및 8비트 지수로 구성됩니다. 다음 예제와 같이 0의 지수는 -126이고 사수는 0입니다. Epsilon 에는 -126의 지수와 1의 가수가 있습니다. 즉, Single.Epsilon 0보다 크고 가능한 가장 작은 값과 지수가 -126인 값에 대해 Single 가능한 가장 작은 증분을 나타내는 가장 작은 양의 Single 값입니다.
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
그러나 Epsilon 속성은 형식의 Single 전체 자릿수에 대한 일반적인 측정값이 아니며 값이 0인 인스턴스에 Single 만 적용됩니다.
참고 항목
속성 값 Epsilon 은 부동 소수점 산술 연산의 반올림으로 인한 상대 오차의 상한을 나타내는 컴퓨터 엡실론과 동일하지 않습니다.
이 상수의 값은 1.4e-45입니다.
두 개의 분명히 동등한 부동 소수점 숫자는 가장 낮은 유효 자릿수의 차이로 인해 같지 않을 수 있습니다. 예를 들어 C# 식 (float)1/3 == (float)0.33333
은 왼쪽의 나누기 연산이 최대 정밀도를 가지지만 오른쪽의 상수는 지정된 자릿수에만 정확하기 때문에 같지 않습니다. 두 부동 소수점 숫자를 같음으로 간주할 수 있는지 여부를 결정하는 사용자 지정 알고리즘을 만드는 경우 상수보다 Epsilon 큰 값을 사용하여 두 값이 같은 것으로 간주될 수 있는 절대 차이 여백을 설정해야 합니다. (일반적으로 차이의 여백은 .보다 Epsilon여러 배 더 큽니다.)
플랫폼 참고 사항
ARM 시스템에서 상수 값 Epsilon 이 너무 작아 감지할 수 없으므로 0과 같습니다. 대신 1.175494351E-38과 같은 대체 엡실론 값을 정의할 수 있습니다.
.NET