ECMA-334: 11.1.7 The decimal type
Microsoft .NET Framework, ASP.NET, Visual C# (CSharp, C Sharp, C-Sharp) Developer Training, Visual Studio
| C# Language Specification |
| © 2006 ECMA International |
11.1.7 The decimal type
The decimal type is a 128-bit data type suitable for financial and monetary calculations. The decimal type
can represent values including those in the range 1 × 10−28 through 1 × 1028 with at least 28 significant digits.
The finite set of values of type decimal are of the form (–1)s × c × 10-e, where the sign s is 0 or 1, the
coefficient c is given by 0 ≤ c < Cmax, and the scale e is such that Emin ≤ e ≤ Emax, where Cmax is at least
1 × 1028, Emin ≤ 0, and Emax ≥ 28. The decimal type does not necessarily support signed zeros, infinities, or NaN's.
A decimal is represented as an integer scaled by a power of ten. For decimals with an absolute value less
than 1.0m, the value is exact to at least the 28th decimal place. For decimals with an absolute value greater
than or equal to 1.0m, the value is exact to at least 28 digits. Contrary to the float and double data types,
decimal fractional numbers such as 0.1 can be represented exactly in the decimal representation. In the
float and double representations, such numbers often have non-terminating binary expansions, making
those representations more prone to round-off errors.
The result of an operation on values of type decimal is that which would result from calculating an exact
result (preserving scale, as defined for each operator) and then rounding to fit the representation. Results are
rounded to the nearest representable value, and, when a result is equally close to two representable values, to
the value that has an even number in the least significant digit position (this is known as “banker’s
rounding”). That is, results are exact to at least the 28th decimal place. Note that rounding may produce a
zero value from a non-zero value.
If a decimal arithmetic operation produces a result whose magnitude is too large for the decimal format, a
System.OverflowException is thrown.
The decimal type has greater precision but may have a smaller range than the floating-point types. Thus,
conversions from the floating-point types to decimal might produce overflow exceptions, and conversions
from decimal to the floating-point types might cause loss of precision or overflow exceptions. For these
reasons, no implicit conversions exist between the floating-point types and decimal, and without explicit
casts, a compile-time error occurs when floating-point and decimal operands are directly mixed in the
same expression.