3

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, that is where my issues are coming from, I really need it to just display the 579.99; but any round, be it decimal.Round or Math.Round still return 580; even the string formats for {0:F} return 580.00.

How can i properly do this?

Community
  • 1
  • 1

1 Answers1

10

New answer (to new question)

Okay, so you've got a value of 579.99722222222222222222222222 - and you're asking that to be rounded to two decimal places. Isn't 580.00 the natural answer? It's closer to the original value than 579.99 is. It sounds like you essentially want flooring behaviour, but with a given number of digits. For that, 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)

Sounds like you've 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;

That's assigning payTotal to a double variable. The value you've actually got is 2087975.69999999995343387126922607421875, which isn't what you wanted. Any time you find yourself casting from double to decimal or vice versa, you should be worried: chances are you've used the wrong type somewhere. Currency values should absolutely be stored in decimal rather than double (and there are various other Stack Overflow questions talking about when to use which).

See my two articles on floating point for more info:

(Once you've got correct results, formatting them is a different matter of course, but that shouldn't be too bad...)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • @zackrspv: As I can see, the value is 2087990... and this is the first time you've even mentioned `dTotal`. I've given a short but complete program showing the calculation working. Can you give a similar one with it *not* working? – Jon Skeet Mar 15 '12 at 21:50
  • @zackrspv: *Completely* changing the question feels against the spirit of the site to me - it makes any existing answers look completely wrong. As it happens I'm around to change my answer, but in future I'd suggest editing the question to *include* the old one. (At least you have acknowledged that it's "recreated".) – Jon Skeet Mar 15 '12 at 22:08
  • @zackrspv: No, you should learn to come up with short but complete programs which demonstrate the same problem, but without using anything proprietary. In this case it's particularly easy to do. I've updated my answer, by the way. – Jon Skeet Mar 15 '12 at 22:13
  • @zackrspv: Have rolled back your edit - now that I've *answered* the edited question, you might as well leave it there... otherwise you've wasted my time *twice*. – Jon Skeet Mar 15 '12 at 22:14