我们使用这些双倍值来表示账单金额。我读到最好使用'十进制"数据类型而不是double,以最小化舍入错误。但它是一个非常大的项目,并将所有dataypes更改为十进制是一项艰巨的任务。 所以我们尝试使用两种中点舍入的Math.Round,但没有任何效果。有一些错误。 反正有没有准确地舍入到小数点后2位?
修改
很抱歉没有提供示例。问题是一旦值(完全有24"双"值)在舍入之前添加(它们原来最多15个位置),总和值达到18167.04这是期望的。但是当它们四舍五入到小数点后2位(使用Math.Round或Math.Round和MidpointRounding)时,求和值为18167.07(相差.03)。
使用Decimal数据类型适合进行货币计算,但由于它是一个庞大的项目,目前,实现数据类型的更改是一项任务。 Rounding无法正常工作。 问题是真的在这里使用数据类型还是因为舍入? 如果使用decimal数据类型,则使用相同的Rounding方法吗?
答案 0 :(得分:0)
浮点精度不是由小数点定义的,而是由有效数字定义。 123456789123456789.0不比0.123456789123456789更准确或更准确。
答案 1 :(得分:0)
在编程中处理财务价值时经常会出现问题:
浮动值不能很好地反映小数。
许多开发人员倾向于将浮点值视为小数,因为当将它们转换为字符串时,它们主要由这些值表示,反之亦然。 情况并非如此。 Float值的小数部分存储为二进制分数,如同here所示。
这使浮点值(及其计算)从它们的十进制表示略微偏斜。
解决这个问题的一种方法是(正如你所说的)使用数据类型decimal
,这种数据类型被构造为进行必须直接转换为小数部分的计算(如财务计算所做的那样)。
另一种方法是在显示或存储浮点计算之前对其进行舍入。对于财务计算,应使用:
Math.Round([your value here], 2, MidpointRounding.AwayFromZero);
我建议尽可能选择前者。计算完成后,很多人都很头疼。通过舍入方法,必须在许多点考虑舍入误差。将现有项目转换为十进制可能是一项重大任务,但从长远来看,它最有可能得到支付(如果可能的话,在第一位)......
关于您的修改:
出现这个问题,因为如果你总结之前的,那么舍入错误就会累积。您可以选择在总结未舍入值后对总和进行四舍五入。在这方面,无论你使用double还是decimal都是相关的,因为这适用于两者。
是否允许这取决于您的财务计算类型。 如果输出以打印形式出现在例如发票,然后最可能不允许这样做。