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 money) should be used, further pointing towards the appropriateness of the type for financial data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With