3

在c#中

double tmp = 3.0 * 0.05;

tmp = 0.15000000000000002

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

有哪些方法可以得到正确的数字(即 0.15,如果小数足够高,则为 0.16)。

4

6 回答 6

14

使用定点变量类型或十进制浮点类型,如 Decimal。浮点数总是有些不准确,二进制浮点表示在与基数 2 进行转换时又增加了一层不准确性。

于 2008-10-07T16:39:40.943 回答
5

钱应该存储为decimal,这是一个浮点小数点类型。其他数据也是如此,这些数据实际上是离散的而不是连续的,并且在逻辑上本质上是十进制的。

出于显而易见的原因,人类对小数有偏见,因此货币等“人造”数量往往更适合小数形式。“自然”量(质量、高度)具有更连续的尺度,这意味着float/ double(它们是浮点二进制点类型)通常(但不总是)更合适。

于 2008-10-07T16:49:53.200 回答
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

于 2008-10-07T16:44:25.427 回答
0

“十进制”类型是专门为此设计的

于 2008-10-07T16:41:08.383 回答
0

数据类型可以decimal很好地工作,并且可能是您的选择。

但是,在过去,我已经能够使用定点整数以优化的方式做到这一点。它是高性能计算的理想之选,在这种情况decimal下,您不能有float.

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

定点数通常可以像任何其他整数一样添加/sub/mul/div,在 mul/div 周围进行一些工作以避免溢出。

于 2008-10-07T17:01:25.410 回答
0

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

我可以在 .NET 中使用“System.Currency”吗?

并参考这个舍入

于 2008-10-08T03:38:42.143 回答