# 4.1.6 Floating point types

**Visual Studio .NET 2003**

C# supports two floating point types: `float`

and `double`

. The `float`

and `double`

types are represented using the 32-bit single-precision and 64-bit double-precision IEEE 754 formats, which provide the following sets of values:

- Positive zero and negative zero. In most situations, positive zero and negative zero behave identically as the simple value zero, but certain operations distinguish between the two (Section 7.7.2).
- Positive infinity and negative infinity. Infinities are produced by such operations as dividing a non-zero number by zero. For example,
`1.0`

`/`

`0.0`

yields positive infinity, and`–1.0`

`/`

`0.0`

yields negative infinity. - The Not-a-Number value, often abbreviated NaN. NaN's are produced by invalid floating-point operations, such as dividing zero by zero.
- The finite set of non-zero values of the form
*s*×*m*× 2, where^{e}*s*is 1 or −1, and*m*and*e*are determined by the particular floating-point type: For`float`

, 0 <*m*< 2^{24}and −149 ≤*e*≤ 104, and for`double`

, 0 <*m*< 2^{53}and −1075 ≤*e*≤ 970. Denormalized floating-point numbers are considered valid non-zero values.

The `float`

type can represent values ranging from approximately 1.5 × 10−^{45} to 3.4 × 10^{38} with a precision of 7 digits.

The `double`

type can represent values ranging from approximately 5.0 × 10−^{324} to 1.7 × 10^{308} with a precision of 15-16 digits.

If one of the operands of a binary operator is of a floating-point type, then the other operand must be of an integral type or a floating-point type, and the operation is evaluated as follows:

- If one of the operands is of an integral type, then that operand is converted to the floating-point type of the other operand.
- Then, if either of the operands is of type
`double`

, the other operand is converted to`double`

, the operation is performed using at least`double`

range and precision, and the type of the result is`double`

(or`bool`

for the relational operators). - Otherwise, the operation is performed using at least
`float`

range and precision, and the type of the result is`float`

(or`bool`

for the relational operators).

The floating-point operators, including the assignment operators, never produce exceptions. Instead, in exceptional situations, floating-point operations produce zero, infinity, or NaN, as described below:

- If the result of a floating-point operation is too small for the destination format, the result of the operation becomes positive zero or negative zero.
- If the result of a floating-point operation is too large for the destination format, the result of the operation becomes positive infinity or negative infinity.
- If a floating-point operation is invalid, the result of the operation becomes NaN.
- If one or both operands of a floating-point operation is NaN, the result of the operation becomes NaN.

Floating-point operations may be performed with higher precision than the result type of the operation. For example, some hardware architectures support an "extended" or "long double" floating-point type with greater range and precision than the `double`

type, and implicitly perform all floating-point operations using this higher precision type. Only at excessive cost in performance can such hardware architectures be made to perform floating-point operations with *less* precision, and rather than require an implementation to forfeit both performance and precision, C# allows a higher precision type to be used for all floating-point operations. Other than delivering more precise results, this rarely has any measurable effects. However, in expressions of the form `x`

`*`

`y`

`/`

`z`

, where the multiplication produces a result that is outside the `double`

range, but the subsequent division brings the temporary result back into the `double`

range, the fact that the expression is evaluated in a higher range format may cause a finite result to be produced instead of an infinity.