Home » c# » Decimal vs Float (Single) or Double

Decimal vs Float (Single) or Double

money-016 When you need to deal with a number that is a fraction, what do you specify for its type?  If you are like most programmers I know, you’ll reach for Float (Single if you are using VB) or Double.

If you are working with currency, though, this could get you into a lot of trouble.

Here’s why.

When you store a number into a float, you are not storing an exact number.  This is because the number you are storing is an approximation of the number you entered.  When you store a number, the integer portion of the number gets priority and the fractional part gets entered as close as is possible given the size of the type you are storing it as.

That is, a Double will be able to save the information more accurately than the Float, but neither of them will store the information precisely.

And that’s just storing a number we enter directly.  What happens if we need to multiply or divide that number?

For simplicity, let’s just say we need to divide a dollar by three.  How would that get stored accurately into a float or a double?  The answer is that it won’t.  It will store as many threes on the right side of the decimal as possible.

This is what the Decimal data type was created for.  A decimal data type deals with the data more like we would if we were dealing with the problem with paper and pencil.  In effect, a decimal data type is similar to an integer that has a decimal point.

Let me illustrate.  Let’s imagine that we have an integer that holds our value and another that holds how many decimal places the value has.

int mainValue;
int decmialPlaces;

To represent a dollar we would say:

mainValue = 100;
decimalPlaces = 2;

Now, we want to divide our dollar by three:

mainValue = mainValue / 3;

obviously, mainValue will end up with 33 as a value, which means our result is .33, exactly what we would expect if we did this computation by hand.

If we multiplied the result by 3, we’d get .99, which is what we’d expect.  We still have to account for that lost penny, but we would deal with the lost penny using standard accounting practices.

Fortunately, we don’t have to go to all that trouble because this is exactly why the decimal type was created for us.

decimal money = 1.00M;
money = money / 3;

I once went to consult in a project that was entirely currency based.  It was basically an accounting package.  This application was not only dealing with money, but it also had to deal with conversion rates between countries.  They wanted to know why they were losing pennies when they converted from one currency to another when the entire application was using floats (not even doubles) instead of decimal values.  That handled most of the problem for them.  The second recommendation I had was to choose a base currency type and always convert from that currency to all of the other countries rather than converting from country A to country B and then back to country A.


Other post in c#

Related Post

  • CSharp Numeric OverflowsCSharp Numeric Overflows Did you know that when you are dealing with numbers, by default, .NET will do, or try to do exactly what you tell it to do?  If you tell it to do the impossible, it will do the next […]
  • .Net String Pool – Not Just For The Compiler.Net String Pool – Not Just For The Compiler On Monday, I was corrected in my assertion that creating multiple empty strings would create multiple objects.  Turns out the compiler automatically puts all of the strings that are […]
  • VB.NET Nullable TypesVB.NET Nullable Types SQL has long had the ability to specify that a value is NULL even if it is a primitive type, but the only way you could have a NULL value in VB.NET is if you were dealing with an […]
  • C# Self Executing Anonymous FunctionC# Self Executing Anonymous Function Not because it is all that new, but because it took me a while to find it, here’s how to create a self executing anonymous function using CSharp, just like you can do in […]
  • VB.NET – Char from String with Option StrictVB.NET – Char from String with Option Strict So here's the question: I'm using String.Split() and need to pass in a Char or a Char array as the parameter.  If I pass in a string String.Split("/") I get an error "Option Strict […]

About Dave Bush

Dave Bush is a Full Stack ASP.NET developer focusing on ASP.NET, C#, Node.js, JavaScript, HTML, CSS, BootStrap, and Angular.JS.Does your team need additional help in any of the above? Contact Dave today.

  • Thanks. I was going to build a Micro Finance project. Your tip regarding decimal data type and base currency type would surely help.