如何修复变量的精度

时间:2008-10-07 16:38:05

标签: c# .net math

在c#

double tmp = 3.0 * 0.05;

tmp = 0.15000000000000002

这与金钱有关。价值实际为0.15美元,但系统希望将其四舍五入至0.16美元。 0.151应该四舍五入到0.16,但不能是0.15000000000000002

有什么方法可以得到正确的数字(如果小数点足够高,则为0.15或0.16)。

6 个答案:

答案 0 :(得分:14)

使用定点变量类型或基数十浮点类型(如Decimal)。浮点数总是有些不准确,二进制浮点表示在转换为/从基数2时会增加另一层不准确。

答案 1 :(得分:5)

资金应存储为decimal,即floating decimal point type。其他数据也是如此,这些数据实际上是离散的而不是连续的,本质上是逻辑十进制的。

由于显而易见的原因,人类对十进制有偏差,因此“人工”数量(例如金钱)往往更适合十进制形式。 “自然”数量(质量,高度)是更连续的,这意味着float / doublefloating binary point types)通常(但不总是)更合适。 / p>

答案 2 :(得分:2)

在企业应用程序架构模式中,Martin Fowler建议使用Money抽象

http://martinfowler.com/eaaCatalog/money.html

大部分时间他都是为了处理货币,而且也是精确的。

您可以在此Google图书搜索结果中看到一些内容:

http://books.google.com/books?id=FyWZt5DdvFkC&pg=PT520&lpg=PT520&dq=money+martin+fowler&source=web&ots=eEys-C_vdA&sig=jckdxgMLSRJtGDYZtcbYST1ak8M&hl=en&sa=X&oi=book_result&resnum=6&ct=result

答案 3 :(得分:0)

'decimal'类型专为此

设计

答案 4 :(得分:0)

decimal数据类型效果很好,可能是您的选择。

然而,在过去,我已经能够使用定点整数以优化的方式完成此操作。它是高性能计算的理想选择,decimal陷入困境,你不能有float的小精度误差。

首先,说Int32,然后分成两半。前半部分是整数部分,后半部分是分数部分。你得到16位有符号整数加上16位小数精度。例如1.5作为16:16的固定点将表示为0x00018000。或者,改变位的分布以满足您的需求。

固定点数通常可以像任何其他整数一样添加/ sub / mul / div,只需稍微处理mul / div就可以避免溢出。

答案 5 :(得分:0)

你所面对的是一个舍入问题,我在前面的另一篇文章中提到过

Can I use “System.Currency” in .NET?

并参考此Rounding