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.

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 […]
  • Help! I deleted my DotNetNuke page or moduleHelp! I deleted my DotNetNuke page or module Today, we are going to look at another commonly over looked feature of DotNetNuke and once again, this feature is not only one that can chew up a lot of space if you don't know about it, […]
  • Two Interfaces, One Method, Two Meanings (VB)Two Interfaces, One Method, Two Meanings (VB) Last week I showed how to implement two interfaces with one method and two meanings in CSharp.  One of the first comments I received for this post was, "How does this work in […]
  • DotNetNuke Modules – Retrieving SettingsDotNetNuke Modules – Retrieving Settings On Monday we discussed how to save setting information for our modules.  Today we want to pick back up where we left off and deal with retrieving that information, both in the […]
  • Why you can’t cast an integer to a string.Why you can’t cast an integer to a string. I saw this question last Thursday on Channel 9 that I've heard before. My guess is that there are enough people who have the same question that it's worth addressing. I know there's […]

About Dave Bush

Dave Bush is a .NET programmer and Certified ScrumMaster who is passionate about managing risk as it relates to developing software. When he is not writing or speaking about topics related to Application Lifecycle Risk Management (ALRM), he is an example to his peers as he develops web sites in the ASP.NET environment using industry best practices.

  • http://www.solutionrally.com Brij Sharma

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

Awards & Certs