- A+

We are working with financial calculations. I found this post about storing money values as decimals: decimal vs double! - Which one should I use and when?

So I'm storing amount as decimals.

I have the following calculation: 12.000 * (1/12) = 1.000

If I use a decimal data type for storing the amount and the result amount I not get the expected result

`// First approach: decimal ratio = 1m / 12m; decimal amount = 12000; decimal ratioAmount = amount * ratio; ratioAmount = 999.9999999999999 // Second approach: double ratio = 1d / 12d; decimal amount = 12000; decimal ratioAmount = (decimal)((double)amount * ratio); ratioAmount = 1.000 // Third approach: double ratio = 1d / 12d; double amount = 12000; double ratioAmount = amount * ratio; ratioAmount = 1.000 `

What is the best way? Everyone is talking about that amounts/money must be stored as decimals.

Never, ever, ever, ever store financial amounts in a double. Here's an example from my blog that shows why `double`

shouldn't be used:

`var lineValues = new List<double> { 1675.89, 2600.21, 5879.79, 5367.51, 8090.30, 492.97, 7888.60 }; double dblAvailable = 31995.27d; double dblTotal = 0d; foreach (var lineValue in lineValues) { dblTotal += lineValue; } if (dblAvailable < dblTotal) { Console.WriteLine("They don't add up!"); } `

You'll see that the `Console.WriteLine`

will be hit because the doubles actually add up to **31995.270000000004**. As you may be able to guess from the names of the variables, this code example was based on some actual code in a finance system - this issue caused users to not be able to correctly allocate amounts to transactions.

Adding the numbers up as `decimal`

s with this additional code:

`decimal decAvailable = (decimal)dblAvailable; decimal decTotal = (decimal)dblTotal; if (decAvailable < decTotal) { Console.WriteLine("They still don't add up!"); } `

*Won't* hit the `Console.WriteLine`

. The moral of the story: use `decimal`

for financial calculations!

The very first part of the language reference for the decimal keyword states:

Compared to other floating-point types, the

`decimal`

type has more precision and a smaller range, which makes it appropriate for financial and monetary calculations.

It's also worthy of note that for a numeric literal to be treated as a decimal, the suffix `m`

(for **m**oney) should be used, further pointing towards the appropriateness of the type for financial data.