在c#中
double tmp = 3.0 * 0.05;
tmp = 0.15000000000000002
这与金钱有关。该值实际上是 0.15 美元,但系统希望将其四舍五入到 0.16 美元。0.151 应该四舍五入到 0.16,但不是 0.15000000000000002
有哪些方法可以得到正确的数字(即 0.15,如果小数足够高,则为 0.16)。
使用定点变量类型或十进制浮点类型,如 Decimal。浮点数总是有些不准确,二进制浮点表示在与基数 2 进行转换时又增加了一层不准确性。
在企业应用架构模式中,Martin Fowler 建议使用 Money 抽象
http://martinfowler.com/eaaCatalog/money.html
大多数情况下,他这样做是为了处理货币,但也是为了精确。
您可以在此 Google 图书搜索结果中看到一些内容:
“十进制”类型是专门为此设计的
数据类型可以decimal
很好地工作,并且可能是您的选择。
但是,在过去,我已经能够使用定点整数以优化的方式做到这一点。它是高性能计算的理想之选,在这种情况decimal
下,您不能有float
.
从一个 开始Int32
,然后分成两半。前半部分是整数部分,后半部分是小数部分。你得到 16 位有符号整数加上 16 位小数精度。例如 1.5 作为 16:16 的固定点将表示为0x00018000
。或者,更改位的分布以满足您的需要。
定点数通常可以像任何其他整数一样添加/sub/mul/div,在 mul/div 周围进行一些工作以避免溢出。