System.Double Structure

Represents a double-precision floating-point number.

See Also: Double Members

Syntax

[System.Runtime.InteropServices.ComVisible(true)]
public struct Double : IComparable, IComparable<double>, IConvertible, IEquatable<double>, IFormattable

Remarks

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, double.PositiveInfinity, double.NegativeInfinity, and not a number (double.NaN). 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.

This topic consists of the following sections:

Floating-Point Representation and Precision

The double data type stores double-precision floating-point values in a 64-bit binary format, as shown in the following table:

Significand or mantissa

0-51

Exponent

52-62

Sign (0 = Positive, 1 = Negative)

63

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

code reference: System.Double.Structure#3

Because some numbers cannot be represented exactly as fractional binary values, floating-point numbers can only approximate real numbers.

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. 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. 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. Its least significant digit is thousandths, whereas the most significant digit in the product is 1.

code reference: System.Double.Structure#4

The limited precision of a floating-point number has several consequences:

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. For example, the result of assigning a literal double value may differ in the 32-bit and 64-bit versions of the .NET Framework. 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. Note that the result of the double.Parse(string) method in this case does not suffer from a loss of precision.

code reference: System.Double.Class.Precision#1

Testing for Equality

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. As a result, calls to the double.Equals(double) method to determine whether two values are equal, or calls to the double.CompareTo(double) method to determine the relationship between two double values, often yield unexpected results. 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.

code reference: System.Double.Structure#9

Calculated values that follow different code paths and that are manipulated in different ways often prove to be unequal. In the following example, one double value is squared, and then the square root is calculated to restore the original value. 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. Although the two values appear to be identical, a call to the double.Equals(double) method indicates that they are not equal. 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.

code reference: System.Double.Structure#10

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 double.Equals(double) or double.CompareTo(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. Instead, in exceptional situations, the result of a floating-point operation is zero, positive infinity, negative infinity, or not a number (NaN):

Floating-Point Functionality

The double structure and related types provide methods to perform operations in the following areas:

Thread Safety

This type is safe for multithreaded operations.

Requirements

Namespace: System
Assembly: mscorlib (in mscorlib.dll)
Assembly Versions: 1.0.5000.0, 2.0.0.0, 4.0.0.0