# Floating-point numeric types (C# reference)

The floating-point types are a subset of the simple types and can be initialized with literals. All floating-point types are also value types. All floating-point numeric types support arithmetic, comparison, and equality operators.

## Characteristics of the floating-point types

C# supports the following predefined floating-point types:

C# type/keyword Approximate range Precision .NET type
float ±1.5 x 10−45 to ±3.4 x 1038 ~6-9 digits System.Single
double ±5.0 × 10−324 to ±1.7 × 10308 ~15-17 digits System.Double
decimal ±1.0 x 10-28 to ±7.9228 x 1028 28-29 digits System.Decimal

In the preceding table, each C# type keyword from the leftmost column is an alias for the corresponding .NET type. They are interchangeable. For example, the following declarations declare variables of the same type:

double a = 12.3;
System.Double b = 12.3;


The default value of each floating-point type is zero, 0. Each of the floating-point types has the MinValue and MaxValue constants that provide the minimum and maximum finite value of that type. The float and double types also provide constants that represent not-a-number and infinity values. For example, the double type provides the following constants: Double.NaN, Double.NegativeInfinity, and Double.PositiveInfinity.

Because the decimal type has more precision and a smaller range than both float and double, it's appropriate for financial and monetary calculations.

You can mix integral types and floating-point types in an expression. In this case, the integral types are converted to floating-point types. The evaluation of the expression is performed according to the following rules:

• If one of the floating-point types is double, the expression evaluates to double, or to bool in relational comparisons or comparisons for equality.
• If there is no double type in the expression, the expression evaluates to float, or to bool in relational comparisons or comparisons for equality.

A floating-point expression can contain the following sets of values:

• Positive and negative zero
• Positive and negative infinity
• Not-a-Number value (NaN)
• The finite set of nonzero values

For more information about these values, see IEEE Standard for Binary Floating-Point Arithmetic, available on the IEEE website.

You can use either standard numeric format strings or custom numeric format strings to format a floating-point value.

## Floating-point literals

By default, a floating-point numeric literal on the right side of the assignment operator is treated as double. You can use suffixes to convert a floating-point or integral literal to a specific type:

• The d or D suffix converts a literal to a double.
• The f or F suffix converts a literal to a float.
• The m or M suffix converts a literal to a decimal.

The following examples show each suffix:

double d = 3D;
d = 4d;
float f = 3.5F;
f = 5.4f;
decimal myMoney = 300.5m;
myMoney = 400.75M;


## Conversions

There's an implicit conversion (called a widening conversion) from float to double because the range of float values is a proper subset of double and there is no loss of precision from float to double.

You must use an explicit cast to convert one floating-point type to another floating-point type when an implicit conversion isn't defined from the source type to the destination type. This is called a narrowing conversion. The explicit case is required because the conversion can result in data loss. There's no implicit conversion between other floating-point types and the decimal type because the decimal type has greater precision than either float or double.