3

我决定重新创建我的问题:

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));

上面的代码返回:

579.99722222222222222222222222

580.00

579.99722222222222222222222222

所以,这就是我的问题的来源,我真的需要它来显示579.99; 但是任何一轮,无论是它decimal.Round还是Math.Round仍然返回580{0:F}甚至return的字符串格式580.00

我怎样才能正确地做到这一点?

4

1 回答 1

10

新答案(新问题)

好的,所以你有一个值579.99722222222222222222222222- 并且你要求将它四舍五入到小数点后两位。580.00 不是自然的答案吗?它比 579.99 更接近原始值。听起来您本质上想要地板行为,但具有给定的位数。为此,您可以使用:

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

在这种情况下,您可以一步完成:

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

...相当于

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

原始答案(原始问题)

听起来您可能payTotal一开始就采用了不合适的形式:

using System;

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

这就是问题:

var payTotal = 2087975.7;

那是分配payTotal给一个double变量。你实际得到的值是 2087975.69999999995343387126922607421875,这不是你想要的。每当您发现自己从doubleto 转换decimal或反之亦然时,您应该担心:您可能在某处使用了错误的类型。货币值绝对应该存储在decimal而不是double(还有各种其他 Stack Overflow 问题讨论何时使用哪个)。

有关更多信息,请参阅我关于浮点的两篇文章:

(一旦你得到正确的结果,格式化它们当然是另一回事,但这应该不会太糟糕......)

于 2012-03-15T21:38:50.817 回答