Correctly rounded financial data

I decided to re-create my question:

decimal dTotal = 0m;
foreach (DictionaryEntry item in _totals)
    {
        if (!string.IsNullOrEmpty(item.Value.ToString()))
        {
            dTotal += Convert.ToDecimal(item.Value);
        }
    }
    Console.WriteLine(dTotal / 3600m);
    Console.WriteLine(decimal.Round(dTotal / 3600m, 2));
    Console.WriteLine(decimal.Divide(dTotal, 3600m));

      

The above code returns:

+579.99722222222222222222222222

580.00

+579.99722222222222222222222222

So this is where my problems come from, I really need to just display 579.99

; but any round, let it decimal.Round

or Math.Round

still return 580

; even string formats for {0:F}

return 580.00

.

How can I get it right?

+3


source to share


1 answer


New answer (to new question)

Okay, so you have a value 579.99722222222222222222222222

- and you're asking to round it to two decimal places. Is 580.00 a natural answer? This is closer to the original value than 579.99. It sounds like you essentially want the behavior of the flooring, but with a given number of digits. To do this, you can use:

var floored = Math.Floor(original * 100) / 100;

      

In this case, you can do both in one step:

var hours = Math.Floor(dTotal / 36) / 100;

      

... which is equivalent to

var hours = Math.Floor((dTotal / 3600) * 100) / 100;

      

Original answer (to original question)



It looks like you probably got payTotal

in an inappropriate form to start with:

using System;

class Test
{
    static void Main()
    {
        decimal pay = 2087975.7m;
        decimal time = pay / 3600;
        Console.WriteLine(time); // Prints 579.99325
    }
}

      

This is the problem:

var payTotal = 2087975.7;

      

payTotal

Variable assignment double

. You actually got 2087975.69999999995343387126922607421875, which is not what you wanted. Every time you turn from a double

to decimal

or vice versa, you should be concerned: most likely, you have used the wrong type somewhere. Currency values ​​should absolutely be stored in decimal

and not double

(and there are various other questions that talk about when to use them).

See my two articles on floating point for more information:

(Once you have the correct results, formatting them is of course a different matter, but it shouldn't be too bad ...)

+10


source







All Articles