在c#
中double tmp = 3.0 * 0.05;
tmp = 0.15000000000000002
这与金钱有关。价值实际为0.15美元,但系统希望将其四舍五入至0.16美元。 0.151应该四舍五入到0.16,但不能是0.15000000000000002
有什么方法可以得到正确的数字(如果小数点足够高,则为0.15或0.16)。
答案 0 :(得分:14)
使用定点变量类型或基数十浮点类型(如Decimal)。浮点数总是有些不准确,二进制浮点表示在转换为/从基数2时会增加另一层不准确。
答案 1 :(得分:5)
资金应存储为decimal
,即floating decimal point type。其他数据也是如此,这些数据实际上是离散的而不是连续的,本质上是逻辑十进制的。
由于显而易见的原因,人类对十进制有偏差,因此“人工”数量(例如金钱)往往更适合十进制形式。 “自然”数量(质量,高度)是更连续的,这意味着float
/ double
(floating binary point types)通常(但不总是)更合适。 / p>
答案 2 :(得分:2)
在企业应用程序架构模式中,Martin Fowler建议使用Money抽象
http://martinfowler.com/eaaCatalog/money.html
大部分时间他都是为了处理货币,而且也是精确的。
您可以在此Google图书搜索结果中看到一些内容:
答案 3 :(得分:0)
'decimal'类型专为此
设计答案 4 :(得分:0)
decimal
数据类型效果很好,可能是您的选择。
然而,在过去,我已经能够使用定点整数以优化的方式完成此操作。它是高性能计算的理想选择,decimal
陷入困境,你不能有float
的小精度误差。
首先,说Int32
,然后分成两半。前半部分是整数部分,后半部分是分数部分。你得到16位有符号整数加上16位小数精度。例如1.5作为16:16的固定点将表示为0x00018000
。或者,改变位的分布以满足您的需求。
固定点数通常可以像任何其他整数一样添加/ sub / mul / div,只需稍微处理mul / div就可以避免溢出。
答案 5 :(得分:0)