' Temperature class stores the value as Double
' and delegates most of the functionality
' to the Double implementation.
Public Class Temperature
Implements IComparable, IFormattable
Public Overloads Function CompareTo(ByVal obj As Object) As Integer _
Implements IComparable.CompareTo
If TypeOf obj Is Temperature Then
Dim temp As Temperature = CType(obj, Temperature)
Return m_value.CompareTo(temp.m_value)
End If
Throw New ArgumentException("object is not a Temperature")
End Function
Public Overloads Function ToString(ByVal format As String, ByVal provider As IFormatProvider) As String _
Implements IFormattable.ToString
If Not (format Is Nothing) Then
If format.Equals("F") Then
Return [String].Format("{0}'F", Me.Value.ToString())
End If
If format.Equals("C") Then
Return [String].Format("{0}'C", Me.Celsius.ToString())
End If
End If
Return m_value.ToString(format, provider)
End Function
' Parses the temperature from a string in form
' [ws][sign]digits['F|'C][ws]
Public Shared Function Parse(ByVal s As String, ByVal styles As NumberStyles, ByVal provider As IFormatProvider) As Temperature
Dim temp As New Temperature()
If s.TrimEnd(Nothing).EndsWith("'F") Then
temp.Value = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2), styles, provider)
Else
If s.TrimEnd(Nothing).EndsWith("'C") Then
temp.Celsius = Double.Parse(s.Remove(s.LastIndexOf("'"c), 2), styles, provider)
Else
temp.Value = Double.Parse(s, styles, provider)
End If
End If
Return temp
End Function
' The value holder
Protected m_value As Double
Public Property Value() As Double
Get
Return m_value
End Get
Set(ByVal Value As Double)
m_value = Value
End Set
End Property
Public Property Celsius() As Double
Get
Return (m_value - 32) / 1.8
End Get
Set(ByVal Value As Double)
m_value = Value * 1.8 + 32
End Set
End Property
End Class

注解

值类型表示双精度64位数字，其值范围从负 1.79769313486232 e 308 到正 1.79769313486232 e 308，以及正或负零、 PositiveInfinity、 NegativeInfinity和非数字（ DoubleNaN).The Double value type represents a double-precision 64-bit number with values ranging from negative 1.79769313486232e308 to positive 1.79769313486232e308, as well as positive or negative zero, PositiveInfinity, NegativeInfinity, and not a number (NaN).它用于表示非常大的值（例如行星或 galaxies 之间的距离）或极小的值（以千克为间隔），并且通常不精确（如从地球到另一颗太阳系的距离），Double类型符合二元浮点算法的 IEC 60559:1989 （IEEE 754）标准。It is intended to represent values that are extremely large (such as distances between planets or galaxies) or extremely small (the molecular mass of a substance in kilograms) and that often are imprecise (such as the distance from earth to another solar system), The Double type complies with the IEC 60559:1989 (IEEE 754) standard for binary floating-point arithmetic.

浮点表示形式和精度Floating-Point Representation and Precision

Double数据类型以64位二进制格式存储双精度浮点值，如下表所示：The Double data type stores double-precision floating-point values in a 64-bit binary format, as shown in the following table:

部件Part

BitsBits

有效位数或尾数Significand or mantissa

0-510-51

加Exponent

52-6252-62

Sign （0 = 正，1 = 负值）Sign (0 = Positive, 1 = Negative)

6363

正如小数部分无法精确表示某些小数值（如1/3 或Math.PI），二进制小数无法表示某些小数值。Just as decimal fractions are unable to precisely represent some fractional values (such as 1/3 or Math.PI), binary fractions are unable to represent some fractional values.例如，1/10 以小数部分的形式精确表示为小数部分，以. 001100110011 表示为二进制小数，模式 "myhpccn-0011" 重复到无限大。For example, 1/10, which is represented precisely by .1 as a decimal fraction, is represented by .001100110011 as a binary fraction, with the pattern "0011" repeating to infinity.在这种情况下，浮点值提供它所表示的数字的不精确表示形式。In this case, the floating-point value provides an imprecise representation of the number that it represents.对原始浮点值执行其他数学运算通常会增加其精度。Performing additional mathematical operations on the original floating-point value often tends to increase its lack of precision.例如，如果将0.1 乘以10并将0.1 添加到 1 9 次，则会看到加法，因为它涉及到8个以上的操作，因此产生的结果不太精确。For example, if we compare the result of multiplying .1 by 10 and adding .1 to .1 nine times, we see that addition, because it has involved eight more operations, has produced the less precise result.请注意，仅当使用 "R"标准数字格式字符串显示这两个DoubleDouble值时，此差异才明显，如有必要，将显示该类型支持的所有17位精度。Note that this disparity is apparent only if we display the two Double values by using the "R" standard numeric format string, which if necessary displays all 17 digits of precision supported by the Double type.

所有浮点数还具有有限数量的有效数字，还决定了浮点值接近于实数的准确程度。All floating-point numbers also have a limited number of significant digits, which also determines how accurately a floating-point value approximates a real number.Double值最多可包含15个小数位数，尽管它在内部维护最大17位数字。A Double value has up to 15 decimal digits of precision, although a maximum of 17 digits is maintained internally.这意味着，某些浮点运算可能缺乏更改浮点值的精度。This means that some floating-point operations may lack the precision to change a floating point value.下面的示例进行了这方面的演示。The following example provides an illustration.它定义了一个非常大的浮点值，然后在其中添加了的Double.Epsilon产品和一个千万亿。It defines a very large floating-point value, and then adds the product of Double.Epsilon and one quadrillion to it.然而，该产品太小，不能修改原始浮点值。The product, however, is too small to modify the original floating-point value.它的最小有效位数为千分之几，而产品中最重要的位是 10-309。Its least significant digit is thousandths, whereas the most significant digit in the product is 10-309.

浮点数的有限精度有几个后果：The limited precision of a floating-point number has several consequences:

对于特定精度，看起来相等的两个浮点数可能不相等，因为其最小有效位不同。Two floating-point numbers that appear equal for a particular precision might not compare equal because their least significant digits are different.在下面的示例中，将一系列数字添加在一起，并将其总计与预期的总数进行比较。In the following example, a series of numbers are added together, and their total is compared with their expected total.尽管这两个值看起来是相同的，但对Equals方法的调用表示它们不是。Although the two values appear to be the same, a call to the Equals method indicates that they are not.

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).

Module Example
Public Sub Main()
Dim values() As Double = { 10.0, 2.88, 2.88, 2.88, 9.0 }
Dim result As Double = 27.64
Dim total As Double
For Each value In values
total += value
Next
If total.Equals(result) Then
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)
End If
End Sub
End Module
' 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).

如果使用的是十进制数，则使用浮点数的算术或比较运算可能不会产生相同的结果，因为二进制浮点数可能不等于十进制数。A mathematical or comparison operation that uses a floating-point number might not yield the same result if a decimal number is used, because the binary floating-point number might not equal the decimal number.前面的示例通过显示乘以0.1 乘以10的结果，再加上1次，阐释了这一点。A previous example illustrated this by displaying the result of multiplying .1 by 10 and adding .1 times.

当包含小数值的数值操作的准确性非常重要时，可以使用Decimal而不Double是类型。When accuracy in numeric operations with fractional values is important, you can use the Decimal rather than the Double type.当具有整数值超出Int64或UInt64类型范围的数值操作的准确性BigInteger很重要时，请使用类型。When accuracy in numeric operations with integral values beyond the range of the Int64 or UInt64 types is important, use the BigInteger type.

如果涉及浮点数，值可能不会往返。A value might not round-trip if a floating-point number is involved.如果某个操作将原始浮点数转换为另一种格式，则会将值转换为舍入，而反向运算会将转换后的窗体转换回浮点数，并且最终浮点数不等于原始的浮点数。A value is said to round-trip if an operation converts an original floating-point number to another form, an inverse operation transforms the converted form back to a floating-point number, and the final floating-point number is not equal to the original floating-point number.往返过程可能会失败，因为在转换过程中一个或多个最小有效位会丢失或更改。The round trip might fail because one or more least significant digits are lost or changed in a conversion.在下面的示例中， Double将三个值转换为字符串，并保存在一个文件中。In the following example, three Double values are converted to strings and saved in a file.但在输出中，即使值看起来相同，还原的值也不等于原始值。As the output shows, however, even though the values appear to be identical, the restored values are not equal to the original values.

与Double值一起使用时，在某些情况下，"R" 格式说明符无法成功往返原始值。When used with a Double value, the "R" format specifier in some cases fails to successfully round-trip the original value.若要确保Double值成功往返，请使用 "G17" 格式说明符。To ensure that Double values successfully round-trip, use the "G17" format specifier.

Single值的精度Double低于值。Single values have less precision than Double values.转换为看似等效Double的Double 值通常不等于值，因为精度存在差异。SingleA Single value that is converted to a seemingly equivalent Double often does not equal the Double value because of differences in precision.在下面的示例中，将相同除法运算的结果分配Double给Single和值。In the following example, the result of identical division operations is assigned to a Double and a Single value.Double在将Single值强制转换为之后，这两个值的比较表明它们不相等。After the Single value is cast to a Double, a comparison of the two values shows that they are unequal.

若要避免此问题，请使用DoubleSingle数据Round类型的位置，或使用方法，使这两个值具有相同的精度。To avoid this problem, use either the Double in place of the Single data type, or use the Round method so that both values have the same precision.

此外，由于DoubleDouble类型的精度丢失，具有值的算术和赋值运算的结果可能会略有不同。In addition, the result of arithmetic and assignment operations with Double values may differ slightly by platform because of the loss of precision of the Double type.例如，在 .NET Framework 的32位和 64 Double位版本中，分配文本值的结果可能不同。For example, the result of assigning a literal Double value may differ in the 32-bit and 64-bit versions of the .NET Framework.下面的示例说明了将文本值 4.42330604244772 e-305 和值为-305 4.42330604244772 的变量分配给Double变量时的这种差异。The following example illustrates this difference when the literal value -4.42330604244772E-305 and a variable whose value is -4.42330604244772E-305 are assigned to a Double variable.请注意，在这种Parse(String)情况下，方法的结果不会受到精度损失。Note that the result of the Parse(String) method in this case does not suffer from a loss of precision.

测试是否相等Testing for Equality

若要将视为相等， Double两个值必须表示相同的值。To be considered equal, two Double values must represent identical values.不过，由于值之间的精度差别，或由于一个或两个值的精度损失，应相同的浮点值经常会出现不相等，因为其最小有效位之间存在差异。However, because of differences in precision between values, or because of a loss of precision by one or both values, floating-point values that are expected to be identical often turn out to be unequal because of differences in their least significant digits.因此，调用Equals方法来确定两个值是否相等，或调用CompareTo方法来确定两个Double值之间的关系，通常会产生意外结果。As a result, calls to the Equals method to determine whether two values are equal, or calls to the CompareTo method to determine the relationship between two Double values, often yield unexpected results.在下面的示例中，这很明显，其中两Double个明显相等的值是不相等的，因为第一个值的精度为15位，而第二个值为17。This is evident in the following example, where two apparently equal Double values turn out to be unequal because the first has 15 digits of precision, while the second has 17.

采用不同的代码路径并以不同的方式操作的计算值通常证明不相等。Calculated values that follow different code paths and that are manipulated in different ways often prove to be unequal.在下面的示例中， Double一个值为平方，然后计算平方根以还原原始值。In the following example, one Double value is squared, and then the square root is calculated to restore the original value.第二Double个比3.51 和 squared 相乘，然后将结果的平方根除以3.51 来还原原始值。A second Double is multiplied by 3.51 and squared before the square root of the result is divided by 3.51 to restore the original value.尽管两个值看起来相同，但对Equals(Double)方法的调用指示它们不相等。Although the two values appear to be identical, a call to the Equals(Double) method indicates that they are not equal.使用 "R" 标准格式字符串返回显示每个 Double 值的所有有效位的结果字符串，显示第二个值小于第一个值 .0000000000001。Using the "R" standard format string to return a result string that displays all the significant digits of each Double value shows that the second value is .0000000000001 less than the first.

如果精度损失可能会影响比较结果，则可以采用以下任意一种方法调用Equals或CompareTo方法：In cases where a loss of precision is likely to affect the result of a comparison, you can adopt any of the following alternatives to calling the Equals or CompareTo method:

Math.Round调用方法以确保这两个值具有相同的精度。Call the Math.Round method to ensure that both values have the same precision.下面的示例修改了上一个示例，以使用此方法，以使两个小数值相等。The following example modifies a previous example to use this approach so that two fractional values are equivalent.

测试近似相等性，而不是相等。Test for approximate equality rather than equality.这要求您定义一个绝对值，而这两个值可以不同，但仍相等，也可以定义较小值与较大值之间的差异。This requires that you define either an absolute amount by which the two values can differ but still be equal, or that you define a relative amount by which the smaller value can diverge from the larger value.

警告

Double.Epsilon在测试相等性时，有时会将其用作两Double个值之间的距离的绝对度量值。Double.Epsilon is sometimes used as an absolute measure of the distance between two Double values when testing for equality.但度量值为零的可添加到或从中减去的Double最小可能值。 Double.EpsilonHowever, Double.Epsilon measures the smallest possible value that can be added to, or subtracted from, a Double whose value is zero.对于大多数正值和负值Double ， Double.Epsilon值太小，无法检测到。For most positive and negative Double values, the value of Double.Epsilon is too small to be detected.因此，除了零值以外，不建议在测试中使用它是否相等。Therefore, except for values that are zero, we do not recommend its use in tests for equality.

下面的示例使用后一种方法来定义IsApproximatelyEqual测试两个值之间的相对差异的方法。The following example uses the latter approach to define an IsApproximatelyEqual method that tests the relative difference between two values.它还比较了对IsApproximatelyEqual方法的调用Equals(Double)和方法的调用结果。It also contrasts the result of calls to the IsApproximatelyEqual method and the Equals(Double) method.

浮点值和异常Floating-Point Values and Exceptions

与整数类型的操作不同，在溢出或非法操作（如被零除）情况下引发异常时，具有浮点值的操作不会引发异常。Unlike operations with integral types, which throw exceptions in cases of overflow or illegal operations such as division by zero, operations with floating-point values do not throw exceptions.相反，在异常情况下，浮点运算的结果为零、正无穷、负无穷或非数字（NaN）：Instead, in exceptional situations, the result of a floating-point operation is zero, positive infinity, negative infinity, or not a number (NaN):

如果浮点运算的结果对于目标格式来说太小，则结果为零。If the result of a floating-point operation is too small for the destination format, the result is zero.当两个非常小的数字相乘时，可能会出现这种情况，如下面的示例所示。This can occur when two very small numbers are multiplied, as the following example shows.

具有无效输入的任何浮点运算。Any floating-point operation with an invalid input.例如，使用负值调用Math.Sqrt方法将返回NaNMath.Acos ，这与使用大于1或小于1的值调用方法时相同。For example, calling the Math.Sqrt method with a negative value returns NaN, as does calling the Math.Acos method with a value that is greater than one or less than negative one.

类型转换和双结构Type conversions and the Double structure

该Double结构不定义任何显式或隐式转换运算符; 相反，转换是由编译器实现的。The Double structure does not define any explicit or implicit conversion operators; instead, conversions are implemented by the compiler.

任何基元数值类型的值转换为Double扩大转换，因此不需要显式强制转换运算符或对转换方法的调用，除非编译器显式要求它。The conversion of the value of any primitive numeric type to a Double is a widening conversion and therefore does not require an explicit cast operator or call to a conversion method unless a compiler explicitly requires it.例如， C#编译器需要一个转换运算符用于从Decimal到Double的转换，而 Visual Basic 编译器则不需要。For example, the C# compiler requires a casting operator for conversions from Decimal to Double, while the Visual Basic compiler does not.下面的示例将其他基元数值类型的最小值或最大值Double转换为。The following example converts the minimum or maximum value of other primitive numeric types to a Double.

Double值到任何其他基元数值数据类型的值的转换是收缩转换，需要转换运算符（在中C#）、转换方法（在 Visual Basic 中）或对Convert方法的调用。The conversion of a Double value to a value of any other primitive numeric data type is a narrowing conversion and requires a cast operator (in C#), a conversion method (in Visual Basic), or a call to a Convert method.超出目标数据类型范围的值（由目标类型的MinValue和MaxValue属性定义）的行为如下表中所示。Values that are outside the range of the target data type, which are defined by the target type's MinValue and MaxValue properties, behave as shown in the following table.

请注意，将Double值转换为另一种数值类型可能会导致精度损失。Note that a loss of precision may result from converting a Double value to another numeric type.在转换非整数Double值的情况下，如示例的输出所示， Double当值舍入（如 Visual Basic）或截断（如中C#）时，小数部分将丢失。In the case of converting non-integral Double values, as the output from the example shows, the fractional component is lost when the Double value is either rounded (as in Visual Basic) or truncated (as in C#).对于DecimalDouble和Single值的转换，此值在目标数据类型中可能没有精确的表示形式。For conversions to Decimal and Single values, the Double value may not have a precise representation in the target data type.

下面的示例将多个Double值转换为多个其他数值类型。The following example converts a number of Double values to several other numeric types.转换在 Visual Basic （默认值）和中C#的已检查上下文中发生（因为有checked关键字）。The conversions occur in a checked context in Visual Basic (the default) and in C# (because of the checked keyword).该示例的输出显示了已检查的未检查上下文中的转换结果。The output from the example shows the result for conversions in both a checked an unchecked context.通过使用/removeintchecks+编译器开关进行编译，并C# checked通过注释掉语句，可以在 Visual Basic 的未检查上下文中执行转换。You can perform conversions in an unchecked context in Visual Basic by compiling with the /removeintchecks+ compiler switch and in C# by commenting out the checked statement.

浮点型功能Floating-Point Functionality

Double结构和相关类型提供了在以下几个方面执行操作的方法：The Double structure and related types provide methods to perform operations in the following areas:

值比较。Comparison of values.您可以调用Equals方法来确定两个Double值是否相等，或CompareTo调用方法来确定两个值之间的关系。You can call the Equals method to determine whether two Double values are equal, or the CompareTo method to determine the relationship between two values.

该Double结构还支持一组完整的比较运算符。The Double structure also supports a complete set of comparison operators.例如，你可以测试是否相等或不相等，或确定一个值是否大于或等于另一个值。For example, you can test for equality or inequality, or determine whether one value is greater than or equal to another.如果其中一个操作数是非的Double数值类型，则在执行比较Double之前将其转换为。If one of the operands is a numeric type other than a Double, it is converted to a Double before performing the comparison.

警告

由于精度之间存在差异，因此Double两个预期相等的值可能会不相等，这将影响比较的结果。Because of differences in precision, two Double values that you expect to be equal may turn out to be unequal, which affects the result of the comparison.有关比较两个Double值的详细信息，请参阅测试相等性部分。See the Testing for Equality section for more information about comparing two Double values.

数学运算。Mathematical operations.常见算术运算（例如加法、减法、乘法和除法）由语言编译器和公共中间语言（CIL）指令实现，而不是通过Double方法实现。Common arithmetic operations, such as addition, subtraction, multiplication, and division, are implemented by language compilers and Common Intermediate Language (CIL) instructions, rather than by Double methods.如果数学运算中的一个操作数为数值类型Double而不是，则在执行运算Double前将其转换为。If one of the operands in a mathematical operation is a numeric type other than a Double, it is converted to a Double before performing the operation.操作的结果也Double是值。The result of the operation is also a Double value.

舍入。Rounding.舍入通常用作一种方法，用于降低由于浮点表示形式和精度问题导致的值之间的差异。Rounding is often used as a technique for reducing the impact of differences between values caused by problems of floating-point representation and precision.可以通过DoubleMath.Round调用方法来舍入值。You can round a Double value by calling the Math.Round method.

分析字符串。Parsing strings.可以通过调用DoubleParse或TryParse方法，将浮点值的字符串表示形式转换为值。You can convert the string representation of a floating-point value to a Double value by calling either the Parse or TryParse method.如果分析操作失败，则该Parse方法将引发异常， TryParse而方法返回false。If the parse operation fails, the Parse method throws an exception, whereas the TryParse method returns false.

类型转换。Type conversion.Double 结构IConvertible为接口提供了显式接口实现，该接口支持任意两个标准 .NET Framework 数据类型之间的转换。The Double structure provides an explicit interface implementation for the IConvertible interface, which supports conversion between any two standard .NET Framework data types.语言编译器还支持将所有其他标准数值类型的值隐式转换为Double值。Language compilers also support the implicit conversion of values of all other standard numeric types to Double values.将任何标准数值类型的值转换为Double扩大转换，不需要使用强制转换运算符或转换方法的用户。Conversion of a value of any standard numeric type to a Double is a widening conversion and does not require the user of a casting operator or conversion method,

但是， Int64和Single值的转换可能会导致精度损失。However, conversion of Int64 and Single values can involve a loss of precision.下表列出了每种类型的精度差异：The following table lists the differences in precision for each of these types:

精确的问题会影响Single转换为Double值的值。The problem of precision most frequently affects Single values that are converted to Double values.在下面的示例中，两个由相同除法运算生成的值是不相等的，因为其中一个值是转换为的Double单精度浮点值。In the following example, two values produced by identical division operations are unequal because one of the values is a single-precision floating point value converted to a Double.

方法

将此实例与指定的双精度浮点数进行比较，并返回一个整数，该整数指示此实例的值是小于、等于还是大于指定双精度浮点数的值。Compares this instance to a specified double-precision floating-point number and returns an integer that indicates whether the value of this instance is less than, equal to, or greater than the value of the specified double-precision floating-point number.

将此实例与指定对象进行比较，并返回一个整数，该整数指示此实例的值是小于、等于还是大于指定对象的值。Compares this instance to a specified object and returns an integer that indicates whether the value of this instance is less than, equal to, or greater than the value of the specified object.

将数字的字符串表示形式转换为它的等效双精度浮点数。Converts the string representation of a number to its double-precision floating-point number equivalent.一个指示转换是否成功的返回值。A return value indicates whether the conversion succeeded or failed.

将指定样式和区域性特定格式的数字的字符串表示形式转换为它的等效双精度浮点数。Converts the string representation of a number in a specified style and culture-specific format to its double-precision floating-point number equivalent.一个指示转换是否成功的返回值。A return value indicates whether the conversion succeeded or failed.

适用于

线程安全性

此类型的所有成员都是线程安全的。All members of this type are thread safe.看似修改实例状态的成员实际上返回用新值初始化的新实例。Members that appear to modify instance state actually return a new instance initialized with the new value.与任何其他类型一样，读取和写入包含此类型的实例的共享变量时，必须通过锁保护以保证线程安全。As with any other type, reading and writing to a shared variable that contains an instance of this type must be protected by a lock to guarantee thread safety.