繁体   English   中英

在C#中将double数据类型的财务值精确舍入到两位小数

[英]Rounding a financial value of double datatype accurately to 2 decimal places in C#

我们使用这些双精度值来表示帐单金额。 我读到最好使用'decimal'数据类型而不是double来最大程度地减少舍入错误,但是它是一个非常大的项目,并且将所有数据类型都更改为十进制是一项艰巨的任务,因此我们尝试了Math.Round和这两种中点舍入,但是没有任何效果,存在某种错误,总有办法精确舍入到小数点后两位小数吗?

编辑:
抱歉,没有提供示例。 问题在于,一旦四舍五入之前添加了这些值(总共有24个“双”值)(它们最初最多有15个位),则求和后的值将达到18167.04。 但是,如果将它们四舍五入到小数点后两位(使用Math.Round或Math.Round和MidpointRounding),则总和为18167.07(相差.03)。

使用Decimal数据类型易于进行货币计算,但由于这是一个庞大的项目,因此,目前,实现数据类型的更改是一项任务。 无法四舍五入。 这里的数据类型确实是问题还是由于四舍五入? 如果使用十进制数据类型,是否可以使用相同的舍入方法?

浮点精度不是由小数点定义的,而是由有效数字定义的。 123456789123456789.0的准确性不超过0.123456789123456789。

在编程中处理财务价值时,经常会出现一个问题:

浮点值不能很好地转换为小数部分

许多开发人员倾向于将float值视为十进制分数,因为在将它们转换为字符串时反之亦然,它们大多由这些值表示。 事实并非如此 浮点值具有它们的小数部分存储为二进制小数 ,如descibed 这里

这使得浮点值(及其计算)与十进制表示形式略有偏差。

解决此问题的一种方法是(如您所述)使用数据类型decimal ,该数据类型被解释为进行必须直接转换为小数部分的计算(就像财务计算一样)。

另一方法是在显示或存储浮点计算的所有结果之前将其取整。 进行财务计算时,应使用:

Math.Round([your value here], 2, MidpointRounding.AwayFromZero);

我建议尽可能选择前者。 完成计算后,这让很多人头疼。 使用舍入方法时,必须在许多点上考虑舍入误差。 将现有项目转换为十进制可能是一项艰巨的任务,但从长远来看(如果有可能,最有可能实现),它最有可能获得回报...

关于您的编辑:

之所以会出现此问题,是因为如果求和之前进行四舍五入,则四舍五入会累积错误。 您可以对未四舍五入的值求和选择四舍五入。 在这方面,无论使用双精度还是十进制都无济于事,因为这两者都适用。

是否允许这样做,取决于您执行的财务计算的类型。 如果加价单以印刷形式出现在例如发票上,则最可能不允许这样做

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM