Stay away from float/double in C#

I stayed away from floating point variables for almost 2 decades now, mainly on the grounds of performance as back in the old days not every CPU even had a dedicated floating point unit in it, but today I decided to use floats in a couple of places and quickly an odd issue came up, here is the test case:

float fGross=1.18f;
float fTax=0.18f;

Console.WriteLine(“Gross: {0}, Tax: {1}, Net of tax: {2}”,fGross,fTax,fGross-fTax);
Nothing fussy here, two fairly small numbers, the only operation we do is substraction so no rounding issues should happen, we only use 2 digits after the dot so the float should handle it, right? Wrong. The printout on screen will be:

Gross: 1.18, Tax: 0.18, Net of tax: 0.9999999

rather than expected result of “Net of tax: 1″.

Using double variables with correct assignment of double precision values: 1.18d (not 1.18f – something that will result in more calculation errors even for initialised types) seems to work (for this test case), however this example shows that staying away from floats is not a bad idea – only use them unless you absolutely have to and if you do then don’t trust the results. Next time I use these data types will be in the next decade if not later.
Some relevant discussion on this topic is here.

6 Responses to “Stay away from float/double in C#”

  1. Stay away from float/double in C# at Away From Here Says:

    [...] Stay away from float/double in C# Nothing fussy here, two fairly small numbers, the only operation we do is substraction so no rounding issues should happen, we only use 2 digits after the dot so the float should handle it, right? Wrong. The printout on screen will be: … [...]

  2. T Says:

    This is normal behavior.
    Since a float or a double can’t represent all possible numbers there is.
    Works the same way in C++ etc.

  3. alexc Says:

    True, I didn’t expect it to keep whole Pi, but I kind of expected it to manage perfectly just 2 digits after the dot. When you deal with money calculation it is best to stick to decimal type in .NET.

  4. Keith Says:

    Should always round your values accordingly anyway, if you’re minimum significant digits is 2, your final result should be rounded to 2 digits as well. In this case, you’ll arrive at your value of 1.0
    Also I think worthy of mentioning is that the performance gain of using a float over a decimal is probably well worth it as well.

  5. Re@PeR Says:

    Comparisons using Float / Double is a big mess, this is also true for C++, not just C#

  6. F.D.Castel Says:

    And after more than 2 decades, people continues to blame a very simple concept (floating point arithmetic) because of what they THINK that SHOULD happen. There is nothing “wrong” with Float/Double, and the link you provide contains plenty of information about this.

Leave a Reply