11.1.5 Floating point types
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 IEC 60559
formats, which provide the
following sets of values:
Chapter 11 Types
93
?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 (?
4.7.2).
?Positive infinity and negative infinity. Infinities are produced by such
operations as dividing a non-zero
number by zero. [Example: For example, 1.0 / 0.0 yields positive infinity,
and .1.0 / 0.0 yields
negative infinity. end example]
?The Not-a-Number value, often abbreviated NaN. NaNs 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 ?2e, where s is 1 or
-1, and m and e are determined
by the particular floating-point type: For float, 0 < m < 224 and -149 = e
= 104, and for double,
0 < m < 253 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 ?1038 with a precision
of 7 digits.
The double type can represent values ranging from approximately 5.0 ?
10-324 to 1.7 ?10308 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.
[Example: 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. end example]