71

我总是在 c# 中告诉 double 类型的变量不适合钱。所有奇怪的事情都可能发生。但我似乎无法创建一个示例来演示其中的一些问题。谁能提供这样的例子?

(编辑;这篇文章最初被标记为 C#;一些回复提到了 的具体细节decimal,因此意味着System.Decimal)。

(编辑 2:我特别要求一些 c# 代码,所以我认为这不仅仅是语言不可知的)

4

8 回答 8

118

非常非常不合适。使用小数。

double x = 3.65, y = 0.05, z = 3.7;
Console.WriteLine((x + y) == z); // false

(来自 Jon 的页面示例- 推荐阅读;-p

于 2008-11-25T08:50:55.520 回答
34

四舍五入会导致您有效地得到奇怪的错误。此外,与精确值的比较非常棘手——您通常需要应用某种 epsilon 来检查实际值是否“接近”特定值。

这是一个具体的例子:

using System;

class Test
{
    static void Main()
    {
        double x = 0.1;
        double y = x + x + x;
        Console.WriteLine(y == 0.3); // Prints False
    }
}
于 2008-11-25T08:54:58.570 回答
7

是的,不合适。

如果我没记错的话 double 大约有 17 个有效数字,所以通常舍入错误会发生在小数点后面很远的地方。大多数财务软件在小数点后使用 4 位小数,剩下 13 位小数可供使用,因此您可以用于单个操作的最大数字仍然远远高于美国国债。但舍入误差会随着时间的推移而增加。如果您的软件运行了很长时间,您最终会开始亏损。某些操作会使情况变得更糟。例如,将大量添加到少量将导致精度显着下降。

您需要定点数据类型来进行货币操作,大多数人不介意您在这里和那里损失一分钱,但会计师不像大多数人..

编辑
根据这个网站http://msdn.microsoft.com/en-us/library/678hzkk9.aspx双打实际上有 15 到 16 位有效数字而不是 17。

@Jon Skeet decimal 比 double 更合适,因为它的精度更高,有 28 位或 29 位有效小数。这意味着累积舍入误差变得显着的可能性较小。像 Boojum 提到的定点数据类型(即代表美分或 100 美分的整数)实际上更适合。

于 2008-11-25T09:08:45.873 回答
5

由于decimal使用 10 的倍数的比例因子,因此可以精确表示 0.1 之类的数字。本质上,十进制类型将其表示为 1 / 10 ^ 1,而 adouble将其表示为 104857 / 2 ^ 20(实际上它更像是真的大数/ 2 ^ 1023)。

Adecimal可以精确地表示任何具有最多 28/29 位有效数字(如 0.1)的基数为 10 的值。一个double不能。

于 2008-11-25T09:17:10.520 回答
4

我的理解是,大多数金融系统使用整数表示货币——即,以美分计算所有内容。

IEEE 双精度实际上可以精确地表示 -2^53 到 +2^53 范围内的所有整数。(Hacker's Delight,第 262 页)如果您只使用加法、减法和乘法,并将所有内容保持在此范围内的整数,那么您应该不会看到精度损失。但是,我会非常警惕分裂或更复杂的操作。

于 2008-11-25T09:19:45.477 回答
4

当您不知道自己在做什么时使用 double 是不合适的。

“double”可以代表一万亿美元的金额,误差为 1/90 美分。因此,您将获得高度精确的结果。想计算将一个人送上火星并让他活着回来需要多少钱?双倍会做得很好。

但是对于金钱,通常有非常具体的规则说,一定的计算必须给出一定的结果,而不是其他的。如果您计算的金额非常非常接近 98.135 美元,那么通常会有一条规则确定结果应该是 98.14 美元还是 98.13 美元,您必须遵循该规则并获得所需的结果。

根据您居住的地方,使用 64 位整数来表示美分、便士或戈比或您所在国家/地区的任何最小单位通常都可以正常工作。例如,代表美分的 64 位有符号整数可以代表高达 92,223 万亿美元的价值。32 位整数通常不适合。

于 2015-01-23T12:20:02.703 回答
0

没有双精度数总是会出现舍入错误,如果您在.Net 上,请使用“十进制”...

于 2008-11-25T12:56:18.597 回答
-5

实际上,只要您选择合适的单位, 浮点双精度数就非常适合表示金额。

http://www.idinews.com/moneyRep.html

定点long也是如此。要么消耗 8 个字节,当然比十进制项目 消耗的 16 个字节更可取。

某事是否有效(即产生预期和正确的结果)与投票或个人偏好无关。一项技术要么有效,要么无效。

于 2015-06-08T15:26:03.017 回答