Single.Epsilon 字段

定义

表示大于零的最小正 Single 值。 此字段为常数。

public: float Epsilon = 1.401298E-45;
public const float Epsilon = 1.401298E-45;
val mutable Epsilon : single
Public Const Epsilon As Single  = 1.401298E-45

字段值

Value = 1.401298E-45
Single

注解

Epsilon如果实例的值为零,则属性的值将反映 Single 数值操作或比较中重要的最小正值 Single 。 例如,下面的代码显示零和被 Epsilon 视为不相等的值,而零和一半的值被 Epsilon 视为相等。

using System;

public class Example
{
   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
Module Example
   Public Sub Main()
      Dim values() As Single = { 0, Single.Epsilon, Single.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 = 1.401298E-45: False
'       0 = 0: True
'       
'       1.401298E-45 = 0: False

更准确地说,单精度浮点格式由符号、23位尾数或有效位数以及8位指数组成。 如下面的示例所示,零的指数为-126,尾数为0。 Epsilon 的指数为-126,尾数为1。 这意味着, Single.Epsilon 为大于零的最小正值, Single 表示 Single 其指数为-126 的的最小可能值和最小可能增量。

using System;

public class Example
{
   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
Module Example
   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 &h000000FF
      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 &h007FFFFF) Or &h800000, 
                         formattedSingle And &h007FFFFF) 
      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 ; 它仅适用于值为 Single 零的实例。

备注

此属性的值 Epsilon 不等效于计算机 epsilon,后者表示相对错误的上限,原因是浮点算法中的舍入。

此常量的值为 1.4 e-45。

两个显然等效的浮点数可能不相等,因为其最小有效位之间存在差异。 例如,c # 表达式不 (float)1/3 == (float)0.33333 比较相等,因为左侧的除法运算具有最大的精度,而右侧的常数仅精确到指定的位数。 如果您创建了一个自定义算法来确定是否可以将两个浮点数视为相等,则必须使用大于该常数的值, Epsilon 以便为两个要视为相等的两个值建立可接受的绝对差值。 (通常情况下,差值幅度比更多 Epsilon 。 )

平台说明

ARM 系统上的 Epsilon 常量值太小,无法检测到,因此它等于零。 可以改为定义等于 1.175494351 E-38 的备用 epsilon 值。

适用于