In this article, we are going to cover floating-point types in C#. Our focus will be mainly on Double, Float and Decimal data types. We have covered the basic data types extensively, and you can check out this article if you feel the need to brush up on the basics.

To download the source code for this article, you can visit our GitHub repository.

Let’s start.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

What Are Floating-Point Types in C#?

These are data types that we use to represent values with decimal points. In a real-world application, we use this data type for cases where we want an extra level of accuracy when dealing with numbers. The most common use cases are: 

  • Recording measurements
  • Recording amounts of money

We will use a simple console project to discuss the three floating point types in C#. For that, we can scaffold a new console application in Visual Studio. 

After creating the project, let’s define a new FloatingPointArithmetic class, which we will use in the coming sections of the article.

Float

The float data type belongs to the System.Single .NET struct. We use it to represent both positive and negative values, with a precision of up to 7 digits. This means that we can store relatively large values in memory during the application lifecycle. 

When declaring float variables, we attach the suffix F or f to the value:

float area = 14.5F;

or

float length = 20.5f;

When using float in our applications, we can perform all numeric computations on our variables. However, due to rounding off, we get inaccurate results from these computations.

Let’s demonstrate this accuracy when working with floating point numbers:

public bool FloatSumAndMultiplication(float firstValue, float secondValue, int factor)
{
    float sum = 0F;

    for (var i = 0; i < factor; i++)
    {
        sum += firstValue + secondValue;
    }

    float product = (firstValue + secondValue) * factor;

    return sum == product;
}

We define the FloatSumAndMultiplication method, which takes two float values and one integer. To get the sum of the values, we add the values based on the factor. For instance, if the factor is 2, we add the values twice. To get the product of the values, we add the values and multiply by the factor. 

Calling this method:

floatingArithmetic.FloatSumAndMultiplication(0.1f, 0.5f, 10);

We would expect that sum and product are equal. However, by printing both values, we get: 

Sum: 5.9999995
Product: 6

For sum, we loop nine times performing the same computation, while product we only do the computation once. We get different results because looping gives us less precise results when working with float.

Double

The double data type belongs to the System.Double .NET struct. We use the double type to represent values with up 15 digits of precision. Simply put, with higher precision, we can represent more information using the double data type. In memory, we reserve 64 bits when we use this data type. 

When declaring variables of double type, we add a suffix D or d to the value: 

double length = 4.5D;

or

double total = 20.3d;

Similar to float, the results we get when we perform numeric calculations using the double type lack accuracy, because of rounding off errors.

Let’s demonstrate using double in mathematical computations:

public bool DoubleSumAndMultiplication(double firstValue, double secondValue, int factor)
{
    double sum = 0D;

    for (var i = 0; i < factor; i++)
    {
        sum += firstValue + secondValue;
    }

    double product = (firstValue + secondValue) * factor;

    return sum == product;
}

Here we define the DoubleSumAndMultiplication method, which returns either true or false depending on whether the values of sum and product are equal.

Calling the method:

floatingArithmetic.DoubleSumAndMultiplication(0.2D, 1.5D, 10);

We expect sum and product to be equal, but printing results to the console, we get:

Sum: 16.999999999999996
Product: 17

Decimal

The decimal data type belongs to the System.Decimal .NET struct. We use this data type in cases where we need a lot more accuracy with our data. Decimal type occupies 128 bits in memory, which is twice that occupied by double. Also, it has the highest precision of the three floating point types.

We declare a decimal type by adding the suffix M or m to the value:

decimal value = 1.5M

or

decimal value1 = 2.5m

When we use decimal in calculations, we get more accurate results as opposed to double and float that have rounding-off errors. In this case, decimal could come in handy when doing financial computations.

Let’s look at decimal computations:

public bool DecimalSumAndMultiplication(decimal firstValue, decimal secondValue, int factor)
{
    decimal sum = 0M;

    for (var i = 0; i < factor; i++)
    {
        sum += firstValue + secondValue;
    }

    decimal product = (firstValue + secondValue) * factor;

    return sum == product;
}

We pass two decimal parameters and one integer to the DecimalSumAndMultiplication method. Then, we calculate the sum and product of the values. Based on the result of comparing the two values, we return either true or false.

When we call the method:

floatingArithmetic.DecimalSumAndMultiplication(0.2M, 1.5M, 10);

We expect that both sum and product are equal.

Examining the results of the method call, we get:

Sum: 17.0
Product: 17.0

Both sum and product values are equal, and the method returns true. Compared to float and double, the decimal type is the most accurate and most precise.

Use Cases of Floating-Point Types

Having learned about the different types, when should we choose one data type over another? 

The precision of our results is an important factor. In cases where we want to minimize errors, decimal would be a perfect choice. In cases where precision is not the first priority, then either double or float is a choice.

When we want to store large values, depending on the size, we would choose between the three types. Float stores the smallest values, followed by double then decimal. However, the larger values have slower execution speeds compared to float.

Conclusion

In this article, we have covered floating-point types in C#. Handling data in our applications can be quite challenging at first and could impact how our applications perform. With this newly acquired knowledge, we can confidently work with numeric data and improve the quality of our applications. 

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!