此文章由机器翻译。 将光标移到文章的句子上,以查看原文。 更多信息。
译文
原文
信息
您所需的主题如下所示。但此主题未包含在此库中。

Double 结构

表示一个双精度浮点数。

命名空间:  System
程序集:  mscorlib(在 mscorlib.dll 中)

[SerializableAttribute]
[ComVisibleAttribute(true)]
public struct Double : IComparable, IFormattable, 
	IConvertible, IComparable<double>, IEquatable<double>

Double 类型公开以下成员。

  名称说明
公共方法由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持CompareTo(Double)将此实例与指定的双精度浮点数进行比较,并返回一个整数,该整数指示此实例的值是小于、等于还是大于指定双精度浮点数的值。
公共方法由 XNA Framework 提供支持CompareTo(Object)将此实例与指定对象进行比较,并返回一个整数,该整数指示此实例的值是小于、等于还是大于指定对象的值。
公共方法由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持Equals(Double)返回一个值,该值指示此实例和指定的 Double 对象是否表示相同的值。
公共方法由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持Equals(Object)返回一个值,该值指示此实例是否等于指定的对象。 (重写 ValueType.Equals(Object)。)
公共方法由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持GetHashCode返回此实例的哈希代码。 (重写 ValueType.GetHashCode()。)
公共方法由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持GetType获取当前实例的 Type (继承自 Object。)
公共方法由 XNA Framework 提供支持GetTypeCode返回值类型 DoubleTypeCode
公共方法静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持IsInfinity返回一个值,该值指示指定数字是计算为负无穷大还是正无穷大。
公共方法静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持IsNaN返回一个值,该值指示指定的值是否不为数字 (NaN)。
公共方法静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持IsNegativeInfinity返回一个值,通过该值指示指定数字是否计算为负无穷大。
公共方法静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持IsPositiveInfinity返回一个值,通过该值指示指定数字是否计算为正无穷大。
公共方法静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持Parse(String)将数字的字符串表示形式转换为它的等效双精度浮点数。
公共方法静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持Parse(String, NumberStyles)将指定样式的数字的字符串表示形式转换为它的等效双精度浮点数。
公共方法静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持Parse(String, IFormatProvider)将指定的区域性特定格式的数字的字符串表示形式转换为它的等效双精度浮点数。
公共方法静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持Parse(String, NumberStyles, IFormatProvider)将指定样式和区域性特定格式的数字的字符串表示形式转换为它的等效双精度浮点数。
公共方法由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持ToString()将此实例的数值转换为其等效的字符串表示形式。 (重写 ValueType.ToString()。)
公共方法由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持ToString(IFormatProvider)使用指定的区域性特定格式信息,将此实例的数值转换为它的等效字符串表示形式。
公共方法由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持ToString(String)使用指定的格式,将此实例的数值转换为它的等效字符串表示形式。
公共方法由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持ToString(String, IFormatProvider)使用指定的格式和区域性特定格式信息,将此实例的数值转换为它的等效字符串表示形式。
公共方法静态成员受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持TryParse(String, Double)将数字的字符串表示形式转换为它的等效双精度浮点数。 一个指示转换是否成功的返回值。
公共方法静态成员受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持TryParse(String, NumberStyles, IFormatProvider, Double)将指定样式和区域性特定格式的数字的字符串表示形式转换为它的等效双精度浮点数。 一个指示转换是否成功的返回值。
页首

  名称说明
公共运算符静态成员受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持Equality返回一个值,该值指示两个指定的 Double 值是否相等。
公共运算符静态成员受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持GreaterThan返回一个值,该值指示指定的 Double 值是否大于另一个指定的 Double 值。
公共运算符静态成员受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持GreaterThanOrEqual返回一个值,该值指示指定的 Double 值是否大于或等于另一个指定的 Double 值。
公共运算符静态成员受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持Inequality返回一个值,该值指示两个指定的 Double 值是否不相等。
公共运算符静态成员受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持LessThan返回一个值,该值指示指定的 Double 值是否小于另一个指定的 Double 值。
公共运算符静态成员受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持LessThanOrEqual返回一个值,该值指示指定的 Double 值是否小于或等于另一个指定的 Double 值。
页首

  名称说明
公共字段静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持Epsilon表示大于零的最小正 Double 值。 此字段为常数。
公共字段静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持MaxValue表示 Double 的最大可能值。 此字段为常数。
公共字段静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持MinValue表示 Double 的最小可能值。 此字段为常数。
公共字段静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持NaN表示不是数字 (NaN) 的值。 此字段为常数。
公共字段静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持NegativeInfinity表示负无穷。 此字段为常数。
公共字段静态成员由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持PositiveInfinity表示正无穷。 此字段为常数。
页首

  名称说明
显式接口实现私有方法受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持IComparable.CompareTo将当前实例与同一类型的另一个对象进行比较,并返回一个整数,该整数指示当前实例在排序顺序中的位置是位于另一个对象之前、之后还是与其位置相同。
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToBoolean基础结构。有关此成员的说明,请参见 IConvertible.ToBoolean
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToByte基础结构。有关此成员的说明,请参见 IConvertible.ToByte
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToChar基础结构。不支持此转换。 尝试使用此方法将引发 InvalidCastException
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToDateTime基础结构。不支持此转换。 尝试使用此方法将引发 InvalidCastException
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToDecimal基础结构。有关此成员的说明,请参见 IConvertible.ToDecimal
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToDouble基础结构。有关此成员的说明,请参见 IConvertible.ToDouble
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToInt16基础结构。有关此成员的说明,请参见 IConvertible.ToInt16
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToInt32基础结构。有关此成员的说明,请参见 IConvertible.ToInt32
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToInt64基础结构。有关此成员的说明,请参见 IConvertible.ToInt64
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToSByte基础结构。有关此成员的说明,请参见 IConvertible.ToSByte
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToSingle基础结构。有关此成员的说明,请参见 IConvertible.ToSingle
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToType基础结构。有关此成员的说明,请参见 IConvertible.ToType
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToUInt16基础结构。有关此成员的说明,请参见 IConvertible.ToUInt16
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToUInt32基础结构。有关此成员的说明,请参见 IConvertible.ToUInt32
显式接口实现私有方法由 XNA Framework 提供支持IConvertible.ToUInt64基础结构。有关此成员的说明,请参见 IConvertible.ToUInt64
页首

Double 值类型表示一个值介于 -1.79769313486232e308 和 +1.79769313486232e308 之间的双精度 64 位数字,以及 +0 或 -0、PositiveInfinityNegativeInfinity 和非数字 (NaN)。 用于指示非常大 (例如行星或星系之间的距离) 或非常小 (一种实体性的分子量在千克) 和通常不精确 (例如从地球到另一太阳系的距离)的值,Double 类型符合二进制浮点数学的 IEC 60559:1989 (IEEE 754) 标准。

本主题包含以下几节:

浮点表示法和精度

Double 数据类型以 64 位二进制格式存储双精度浮点值,如下表所示:

组成部分

有效位数或尾数

0-51

指数

52-62

Sign (0 = Positive, 1 = Negative)

63

正如为十进制分数无法准确地表示某些小数的值 (例如 1/3 或 Math.PI),二进制分数无法表示某些小数的值。 例如,1/10,由 .1 准确地表示为一个十进制分数,由 .001100110011 表示为二进制分数,该形式的“0011 "无限重复。 在这种情况下,浮点值提供它表示的一个数字的不精确的表示形式。 对原始浮点值的其他数学运算通常倾向于增加其缺少的精度。 例如,如果我们比较 .1乘以10 和 .1 加 .1 九次的结果,我们看到该情况,因为还涉及八个更多操作,产生了更不准确的结果。 注意只有当显示使用“R” standard numeric format string的两个 Double 值时,不一致是明显的,如果必要,它展现了 Double 类型支持的17位精度。


using System;

public class Example
{
   public static void Main()
   {
      Double value = .1;
      Double result1 = value * 10;
      Double result2 = 0;
      for (int ctr = 1; ctr <= 10; ctr++)
         result2 += value;

      Console.WriteLine(".1 * 10:           {0:R}", result1);
      Console.WriteLine(".1 Added 10 times: {0:R}", result2);
   }
}
// The example displays the following output:
//       .1 * 10:           1
//       .1 Added 10 times: 0.99999999999999989


由于某些数字不能正确地以二进制值小数表示,浮点数只能接近于实数。

所有浮点数可能还有有效位的限制数,这决定了浮点值接近实数的准确程度。Double 值的精度总共是 15 个十进制位,但内部维护的最大精度是 17 位。 这意味着一些浮点运算可能缺少精度来更改浮点值。 下面的示例进行了这方面的演示。 它定义一个非常大的浮点值,然后给它加上 Double.Epsilon 和千万亿的乘积。 但是,该产品因过小而无法修改原始浮点值。 其最低有效位是万分之一,而在该结果的最高有效位为 1-312


using System;

public class Example
{
   public static void Main()
   {
      Double value = 123456789012.34567;
      Double additional = Double.Epsilon * 1e12;
      Console.WriteLine("{0} + {1} = {2}", value, additional, 
                                           value + additional);
   }
}
// The example displays the following output:
//    123456789012.346 + 4.94065645841247E-312 = 123456789012.346


浮点数的有限精度有几种结果:

  • 特定精度下看似相等的两个浮点数可能并不相等,因为它们的最小有效位数不同。 在下面的示例中,一系列数字相加,并且将它们的总和与其所需的总和比较。 尽管这两个值显示相同,Equals 方法的调用指示事实并非如此。

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          Double[] values = { 10.0, 2.88, 2.88, 2.88, 9.0 };
          Double result = 27.64;
          Double total = 0;
          foreach (var value in values)
             total += value;
    
          if (total.Equals(result))
             Console.WriteLine("The sum of the values equals the total.");
          else
             Console.WriteLine("The sum of the values ({0}) does not equal the total ({1}).",
                               total, result); 
       }
    }
    // The example displays the following output:
    //      The sum of the values (36.64) does not equal the total (36.64).   
    //
    // If the index items in the Console.WriteLine statement are changed to {0:R},
    // the example displays the following output:
    //       The sum of the values (27.639999999999997) does not equal the total (27.64).   
    
    
    

    如果改变Console.WriteLine(String, Object, Object)语句中的格式项,从 {0}{1}{0:R}{1:R} 来显示两个Double值的所有有效位,明显的,两个值是不相等的,因为在加运算过程中精度丢失。 在这种情况下,该问题可通过在执行比较之前,调用方法 Math.Round(Double, Int32) 舍入 Double 值达到所需的精度。

  • 由于二进制浮点数可能无法等于十进制数,如果使用十进制数,则使用浮点数的数学或比较运算可能不会产生相同的结果。 前面的示例通过显示 .1 乘以 10 和加 .1 的结果阐释了这一点。

    在数字操作与小数值有关的精确度很重要时,可以使用 Decimal 而不是 Double 类型。 在整数值的数字操作的精确度与 Int64UInt64 类型范围重要,请使用 BigInteger 类型。

  • 如果涉及浮点数,值可能不往返。 值的往返是指,某个运算将原始浮点数转换为另一种格式,而反向运算又将转换后的格式转换回浮点数,且最终浮点数与原始浮点数不相等。 由于一个或多个最低有效位在转换中丢失或更改,往返可能会失败。 在下面的示例中,这三个 Double 值转换为字符串并保持在文件中。 不过,如输出所示,即使值显示相同,还原的值与原始值不相等。

    
    using System;
    using System.IO;
    
    public class Example
    {
       public static void Main()
       {
          StreamWriter sw = new StreamWriter(@".\Doubles.dat");
          Double[] values = { 2.2/1.01, 1.0/3, Math.PI };
          for (int ctr = 0; ctr < values.Length; ctr++) {
             sw.Write(values[ctr].ToString());
             if (ctr != values.Length - 1)
                sw.Write("|");
          }      
          sw.Close();
    
          Double[] restoredValues = new Double[values.Length];
          StreamReader sr = new StreamReader(@".\Doubles.dat");
          string temp = sr.ReadToEnd();
          string[] tempStrings = temp.Split('|');
          for (int ctr = 0; ctr < tempStrings.Length; ctr++)
             restoredValues[ctr] = Double.Parse(tempStrings[ctr]);   
    
    
          for (int ctr = 0; ctr < values.Length; ctr++)
             Console.WriteLine("{0} {2} {1}", values[ctr], 
                               restoredValues[ctr],
                               values[ctr].Equals(restoredValues[ctr]) ? "=" : "<>");
       }
    }
    // The example displays the following output:
    //       2.17821782178218 <> 2.17821782178218
    //       0.333333333333333 <> 0.333333333333333
    //       3.14159265358979 <> 3.14159265358979
    
    
    

    在这种情况下,如下面的示例所示,值可以通过使用“R”standard numeric format string往返已成功来保留 Double 值的全部精度。

    
    using System;
    using System.IO;
    
    public class Example
    {
       public static void Main()
       {
          StreamWriter sw = new StreamWriter(@".\Doubles.dat");
          Double[] values = { 2.2/1.01, 1.0/3, Math.PI };
          for (int ctr = 0; ctr < values.Length; ctr++) 
             sw.Write("{0:R}{1}", values[ctr], ctr < values.Length - 1 ? "|" : "" );
    
          sw.Close();
    
          Double[] restoredValues = new Double[values.Length];
          StreamReader sr = new StreamReader(@".\Doubles.dat");
          string temp = sr.ReadToEnd();
          string[] tempStrings = temp.Split('|');
          for (int ctr = 0; ctr < tempStrings.Length; ctr++)
             restoredValues[ctr] = Double.Parse(tempStrings[ctr]);   
    
    
          for (int ctr = 0; ctr < values.Length; ctr++)
             Console.WriteLine("{0} {2} {1}", values[ctr], 
                               restoredValues[ctr],
                               values[ctr].Equals(restoredValues[ctr]) ? "=" : "<>");
       }
    }
    // The example displays the following output:
    //       2.17821782178218 = 2.17821782178218
    //       0.333333333333333 = 0.333333333333333
    //       3.14159265358979 = 3.14159265358979
    
    
    
  • Single 值比 Double 值精度更小。 Single 值转换为表面上等效 Double, 由于在精度上的差异的,通常不等于 Double 值。 在下面的示例中,相同的除法运算的结果分配给 DoubleSingle 值。 Single 值转换为 Double后,两个值的比较指示,它们不相等。

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          Double value1 = 1/3.0;
          Single sValue2 = 1/3.0f;
          Double value2 = (Double) sValue2;
          Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, 
                                              value1.Equals(value2));
       }
    }
    // The example displays the following output:
    //        0.33333333333333331 = 0.3333333432674408: False
    
    
    

    若要避免此问题,请使用 Single 数据类型代替 Double ,或使用 Round 方法,以便两个值具有相同的精度。

此外,由于 Double 类型的精度损失,使用 Double 值进行的算数运算和赋值运算的结果在不同平台上可能稍有不同。 例如,分配文本 Double 值的结果可能在 32 位和 64 位版本的 .NET Framework 中有所不同。 下面的示例阐释了为 Double 变量分配文本值 -4.42330604244772E-305 与分配值为 -4.42330604244772E-305 的变量之间的差异。 请注意在这种情况下,Parse(String) 方法的结果不会受到精度损失。


double value = -4.42330604244772E-305;

double fromLiteral = -4.42330604244772E-305;
double fromVariable = value;
double fromParse = Double.Parse("-4.42330604244772E-305");

Console.WriteLine("Double value from literal: {0,29:R}", fromLiteral);
Console.WriteLine("Double value from variable: {0,28:R}", fromVariable);
Console.WriteLine("Double value from Parse method: {0,24:R}", fromParse);      
// On 32-bit versions of the .NET Framework, the output is:
//    Double value from literal:        -4.42330604244772E-305
//    Double value from variable:       -4.42330604244772E-305
//    Double value from Parse method:   -4.42330604244772E-305
//
// On other versions of the .NET Framework, the output is:
//    Double value from literal:      -4.4233060424477198E-305
//    Double value from variable:     -4.4233060424477198E-305
//    Double value from Parse method:   -4.42330604244772E-305      


相等性测试

要视为相等,两个 Double 值必须表示具有相同的值。 但是,由于在值之间的精度方面的差异,或者由于一个或两个值丢失的精度,由于最低有效位差异,通常应是相同的浮点值结果不相等。 因此,调用 Equals 方法确定两个值是否相等,或调用 CompareTo 方法确定两个 Double 值之间的关系,通常产生意外的结果。 这在下面的示例中是不同的,两个显然相等的 Double 值结果是不相等,因为第一个具有 15 位精度,而第二个具有 17。


using System;

public class Example
{
   public static void Main()
   {
      double value1 = .333333333333333;
      double value2 = 1.0/3;
      Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2));
   }
}
// The example displays the following output:
//        0.333333333333333 = 0.33333333333333331: False


遵循不同的代码路径并以不同的方式进行操作计算的值,通常证明不相等 。 在下面的示例中,一个 Double 值被计算,计算该平方根然后还原原始值。 结果的平方根被 3.51 除之前,一个 Double 乘以 3.51 并平方,来还原原始值。 尽管这两个值显示相同,Equals(Double) 方法的调用指示他们并不相等。 使用“R”标准格式的字符串返回结果将字符串,显示每个双精度值任何有效数字,表示第二个值比第一个小 .0000000000001。


using System;

public class Example
{
   public static void Main()
   {
      double value1 = 100.10142;
      value1 = Math.Sqrt(Math.Pow(value1, 2));
      double value2 = Math.Pow(value1 * 3.51, 2);
      value2 = Math.Sqrt(value2) / 3.51;
      Console.WriteLine("{0} = {1}: {2}\n", 
                        value1, value2, value1.Equals(value2)); 
      Console.WriteLine("{0:R} = {1:R}", value1, value2); 
   }
}
// The example displays the following output:
//    100.10142 = 100.10142: False
//    
//    100.10142 = 100.10141999999999


在精度损失会影响比较结果的情况下,可以采用下列选项中的任何一个调用 EqualsCompareTo 方法:

  • 调用 Math.Round 方法保证两个值具有相同的精度。 下面的示例修改上面的示例,使用此方法以便两个小数值是等效的。

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          double value1 = .333333333333333;
          double value2 = 1.0/3;
          int precision = 7;
          value1 = Math.Round(value1, precision);
          value2 = Math.Round(value2, precision);
          Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2));
       }
    }
    // The example displays the following output:
    //        0.3333333 = 0.3333333: True
    
    
    

    不过,请注意,精度的问题仍然适用于中心点值的舍入。 有关更多信息,请参见 Math.Round(Double, Int32, MidpointRounding) 方法。

  • 测试大致相等而不是相等。 这要求您定义了两个值可能不同但仍相等的绝对量,或者定义更小的值可以从更大值分离的相对量。

    警告说明警告

    当测试相等时,Double.Epsilon 有时用作两个 Double 值之间的距离的绝对度量。但是,Double.Epsilon 度量从值为零的 Double可以添加或减去的最小可能值。 对大多数正和负 Double 值, Double.Epsilon 的值太小而无法检测。 因此,除了为零的值,建议不要用其作相等性测试。

    下面的示例使用后一个途径定义 IsApproximatelyEqual 方法,该方法测试两个值之间的相对差异。 它将对 IsApproximatelyEqual 方法和 Equals(Double) 方法的调用结果进行比较。

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          double one1 = .1 * 10;
          double one2 = 0;
          for (int ctr = 1; ctr <= 10; ctr++)
             one2 += .1;
    
          Console.WriteLine("{0:R} = {1:R}: {2}", one1, one2, one1.Equals(one2));
          Console.WriteLine("{0:R} is approximately equal to {1:R}: {2}", 
                            one1, one2, 
                            IsApproximatelyEqual(one1, one2, .000000001));   
       }
    
       static bool IsApproximatelyEqual(double value1, double value2, double epsilon)
       {
          // If they are equal anyway, just return True.
          if (value1.Equals(value2))
             return true;
    
          // Handle NaN, Infinity.
          if (Double.IsInfinity(value1) | Double.IsNaN(value1))
             return value1.Equals(value2);
          else if (Double.IsInfinity(value2) | Double.IsNaN(value2))
             return value1.Equals(value2);
    
          // Handle zero to avoid division by zero
          double divisor = Math.Max(value1, value2);
          if (divisor.Equals(0)) 
             divisor = Math.Min(value1, value2);
    
          return Math.Abs(value1 - value2)/divisor <= epsilon;           
       } 
    }
    // The example displays the following output:
    //       1 = 0.99999999999999989: False
    //       1 is approximately equal to 0.99999999999999989: True
    
    
    

浮点值和异常

不同于整数类型的操作,在溢出或非法操作(如被零除)情况下引发异常,浮点值的操作不引发异常。 相反,在异常情况,一个浮点运算的结果为零、正无穷大、负无穷大或非数值 (NaN):

  • 如果浮点运算的结果对于目标格式来说太小,则结果为零。 生当两个非常小的数字相乘时则可能发,如下例所示。

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          Double value1 = 1.1632875981534209e-225;
          Double value2 = 9.1642346778e-175;
          Double result = value1 * value2;
          Console.WriteLine("{0} * {1} = {2}", value1, value2, result);
          Console.WriteLine("{0} = 0: {1}", result, result.Equals(0.0));
       }
    }
    // The example displays the following output:
    //       1.16328759815342E-225 * 9.1642346778E-175 = 0
    //       0 = 0: True
    
    
    
  • 如果浮点运算结果的数值对于目标格式来说超过范围,则运算的结果为 PositiveInfinityNegativeInfinity(具体取决于结果的符号)。 运算结果溢出 Double.MaxValuePositiveInfinity, 运算结果溢出Double.MinValueNegativeInfinity,如下面的示例所示。

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          Double value1 = 4.565e153;
          Double value2 = 6.9375e172;
          Double result = value1 * value2;
          Console.WriteLine("PositiveInfinity: {0}", 
                             Double.IsPositiveInfinity(result));
          Console.WriteLine("NegativeInfinity: {0}\n", 
                            Double.IsNegativeInfinity(result));
    
          value1 = -value1;
          result = value1 * value2;
          Console.WriteLine("PositiveInfinity: {0}", 
                             Double.IsPositiveInfinity(result));
          Console.WriteLine("NegativeInfinity: {0}", 
                            Double.IsNegativeInfinity(result));
       }
    }                                                                 
    
    // The example displays the following output:
    //       PositiveInfinity: True
    //       NegativeInfinity: False
    //       
    //       PositiveInfinity: False
    //       NegativeInfinity: True
    
    
    

    正数除零还产生 PositiveInfinity 结果,负数除零产生NegativeInfinity 结果。

  • 如果浮点运算无效,则运算的结果为 NaN 例如,以下操作产生NaN

  • 带有无效输入的任何浮点运算。 例如,调用带负值的 Math.Sqrt 方法返回 NaN,同样的,调用带有大于一或者小于负数的值 Math.Acos 方法。

  • 使用参数值是 Double.NaN的任何操作。

浮点功能

Double 结构和相关类型提供方法来执行以下方面的操作:

  • 值比较 可以调用 Equals 方法确定两个 Double 值是否相等,或 CompareTo 方法确定两个值之间的关系。

    Double 框架还支持整套比较运算符。 例如,可以测试是否相等或不等,或者确定一个值是否大于或等于另一个。 如果某个操作数是数值类型而不是Double,在执行比较之前它将被转换为 Double

    警告说明警告

    由于精度差异,您希望为相同的两个 Double 值可能结果不相等,影响比较结果。 有关比较两个 Double 值的更多信息,请参见 Testing for Equality 部分。

    还可以调用 IsNaNIsInfinityIsPositiveInfinityIsNegativeInfinity 方法测试这些特殊值。

  • 数学运算 常见的算术运算,例如添加,减、乘和除,按语言编译器和公共中间语言 (CIL) 命令实现,而不是使用 Double 方法。 如果其中一个数学运算操作的操作数是一个数值类型而不是Double,在执行操作之前,它将转换为 Double 操作的结果也是 Double 值。

    可以通过调用 System.Math 类中 static (在 Visual Basic 中Shared ) 方法执行其他数学运算。 其中包括其他方法常用于算法 (例如 Math.AbsMath.SignMath.Sqrt),几何图形 (例如 Math.CosMath.Sin) 和 微积分 (例如 Math.Log)。

    还可以操作的单个位按 Double 值。 BitConverter.DoubleToInt64Bits 方法保持 Double 值的位形式在 64 位整数。 BitConverter.GetBytes(Double) 方法返回其字节数组中的位模式。

  • 舍入. 舍入是常用的,则减少差异的影响的方法在浮点表示形式的问题导致的值和精度之间的。 通过调用方法 Math.Round 舍入 Double 值。

  • 格式化. 通过调用 ToString 方法或通过使用符合格式属性,可以将 Double 值转变为它的字符串形式。 有关如何布局的信息字符串控件浮点值的字符串表示方法,请参见 标准数字格式字符串自定义数字格式字符串 主题。

  • 分析字符串. 通过调用 ParseTryParse 方法,您可以将浮点值的字符串表示方法转换为 Double 值。 如果解析操作失败,Parse 方法将引发异常,而 TryParse 方法会返回 false

  • 类型转换 Double framework for IConvertible 接口提供显式接口实现,支持在任意两个标准 .NET Framework 数据类型之间的转换。 语言编译器还支持其他标准数值类型的值隐式转换为 Double 值。 任何标准数值类型的值转换为 Double是一个扩大转换,不需要使用强制转换运算符或转换方法。

    但是,Int64Single 值的转换可能会丢失精度。 下表列出了每一个这些类型的精度差异:

    类型

    最大精度

    内部精度

    Double

    15

    17

    Int64

    19位小数

    19位小数

    Single

    7位小数

    9位小数

    精度的问题经常影响转换为 Double 值的 Single 值。 在下面的示例中,相同的除法运算生成的两个值不相等,原因是其中一个值是转换为 Double的单精度浮点值。

    
    using System;
    
    public class Example
    {
       public static void Main()
       {
          Double value = .1;
          Double result1 = value * 10;
          Double result2 = 0;
          for (int ctr = 1; ctr <= 10; ctr++)
             result2 += value;
    
          Console.WriteLine(".1 * 10:           {0:R}", result1);
          Console.WriteLine(".1 Added 10 times: {0:R}", result2);
       }
    }
    // The example displays the following output:
    //       .1 * 10:           1
    //       .1 Added 10 times: 0.99999999999999989
    
    
    

下面的代码示例演示 Double 的用法:


	// The Temperature class stores the temperature as a Double
	// and delegates most of the functionality to the Double
	// implementation.
	public class Temperature : IComparable, IFormattable 
    {
		// IComparable.CompareTo implementation.
		public int CompareTo(object obj) {
            if (obj == null) return 1;

			Temperature temp = obj as Temperature;
            if (obj != null) 
				return m_value.CompareTo(temp.m_value);
			else
     			throw new ArgumentException("object is not a Temperature");	
		}

		// IFormattable.ToString implementation.
		public string ToString(string format, IFormatProvider provider) {
			if( format != null ) {
				if( format.Equals("F") ) {
					return String.Format("{0}'F", this.Value.ToString());
				}
				if( format.Equals("C") ) {
					return String.Format("{0}'C", this.Celsius.ToString());
				}
			}

			return m_value.ToString(format, provider);
		}

		// Parses the temperature from a string in the form
		// [ws][sign]digits['F|'C][ws]
		public static Temperature Parse(string s, NumberStyles styles, IFormatProvider provider) {
			Temperature temp = new Temperature();

			if( s.TrimEnd(null).EndsWith("'F") ) {
				temp.Value = Double.Parse( s.Remove(s.LastIndexOf('\''), 2), styles, provider);
			}
			else if( s.TrimEnd(null).EndsWith("'C") ) {
				temp.Celsius = Double.Parse( s.Remove(s.LastIndexOf('\''), 2), styles, provider);
			}
			else {
				temp.Value = Double.Parse(s, styles, provider);
			}

			return temp;
		}

		// The value holder
		protected double m_value;

		public double Value {
			get {
				return m_value;
			}
			set {
				m_value = value;
			}
		}

		public double Celsius {
			get {
				return (m_value-32.0)/1.8;
			}
			set {
				m_value = 1.8*value+32.0;
			}
		}
	}


.NET Framework

受以下版本支持:4.5.2、4.5.1、4.5、4、3.5、3.0、2.0、1.1、1.0

.NET Framework Client Profile

受以下版本支持:4、3.5 SP1

可移植类库

受以下版本支持:可移植类库

适用于 Windows 应用商店应用的 .NET

受以下版本支持:Windows 8

适用于 Windows Phone 应用的 .NET

受以下版本支持:Windows Phone 8、Silverlight 8.1

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008(不支持服务器核心角色), Windows Server 2008 R2(支持带 SP1 或更高版本的服务器核心角色;不支持 Itanium)

.NET Framework 并不是对每个平台的所有版本都提供支持。有关支持的版本的列表,请参阅.NET Framework 系统要求

此类型的所有成员都是线程安全的。 看似修改了实例状态的成员实际上返回一个用新值实例化的新实例。 正如对任何其他类型一样,对于包含此类型的实例的共享变量,也必须通过锁定来保护对其进行的读写,以保证实现线程安全。

警告说明警告

在所有的硬件平台上都分配该类型的一个实例不是线程安全的,因为该实例的二进制表示形式可能太大,无法在单个原子操作中分配。

社区附加资源

显示:
© 2015 Microsoft