C# 适当地对财务数据进行四舍五入

C# 适当地对财务数据进行四舍五入,c#,winforms,math,financial,C#,Winforms,Math,Financial,我决定重新创建我的问题: decimal dTotal = 0m; foreach (DictionaryEntry item in _totals) { if (!string.IsNullOrEmpty(item.Value.ToString())) { dTotal += Convert.ToDecimal(item.Value); } } Console.WriteLine(dTotal /

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

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.997222222222

580.00

579.997222222222

所以,这就是我的问题的来源,我真的需要它只显示
579.99
;但是任何一轮,无论是十进制。四舍五入还是数学。四舍五入仍然返回
580
;甚至
{0:F}
的字符串格式返回
580.00

我如何才能正确地做到这一点?

新答案(新问题)

好的,你得到了一个值为579.99722222222,你要求把它四舍五入到小数点后两位。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.69999995343387269222607421875,这不是您想要的。每当你发现自己从
double
转换到
decimal
或反之,你都应该担心:你可能在某处使用了错误的类型。货币值绝对应该存储在
十进制
中,而不是
双精度
(还有其他各种堆栈溢出问题,讨论何时使用哪个)

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


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

尝试除以3600.0,看看是否有效?@simchona它不起作用,int被提升为双精度,这可能是内部表示本身造成的舍入错误。你试过十进制吗?嗨-这两个链接可能会帮助你&&,谢谢不要使用var,显式地按Decimal@zackrspv:如我所见,值是2087990。。。这是你第一次提到
dTotal
。我给出了一个简短但完整的程序,显示了计算的有效性。你能给出一个不起作用的类似问题吗?@zackrspv:完全改变这个问题对我来说有违网站的精神——它让任何现有的答案看起来都是完全错误的。碰巧我会改变我的答案,但将来我会建议编辑这个问题,把原来的问题也包括进去。(至少你已经承认它是“重新创建的”。@zackrspv:不,你应该学会编写简短但完整的程序来演示同样的问题,但不使用任何专有的东西。在这种情况下,这特别容易做到。顺便说一句,我已经更新了我的答案。@zackrspv:已经回滚了您的编辑-既然我已经回答了编辑后的问题,您不妨把它留在那里。。。否则你就浪费了我两次时间。