C# 十进制对双精度我应该使用哪一种,何时使用?

C# 十进制对双精度我应该使用哪一种,何时使用?,c#,double,decimal,precision,currency,C#,Double,Decimal,Precision,Currency,我一直看到有人在C#中使用双打。我知道我在某个地方读到双倍有时会失去准确性。 我的问题是什么时候应该使用double,什么时候应该使用decimal类型? 哪种类型适合进行货币计算?(即超过1亿美元)对于货币:decimal。它需要更多的内存,但不会出现舍入问题,比如有时会出现双精度。对于金钱,总是十进制。这就是它被创造的原因 若数字必须正确相加或平衡,则使用十进制。这包括人们可能手工进行的任何财务存储或计算、分数或其他数字 如果数字的精确值不重要,请使用double表示速度。这包括图形、物理或

我一直看到有人在C#中使用双打。我知道我在某个地方读到双倍有时会失去准确性。 我的问题是什么时候应该使用double,什么时候应该使用decimal类型?
哪种类型适合进行货币计算?(即超过1亿美元)

对于货币:
decimal
。它需要更多的内存,但不会出现舍入问题,比如有时会出现双精度。

对于金钱,总是十进制。这就是它被创造的原因

若数字必须正确相加或平衡,则使用十进制。这包括人们可能手工进行的任何财务存储或计算、分数或其他数字

如果数字的精确值不重要,请使用double表示速度。这包括图形、物理或其他物理科学计算,其中已经有“有效数字数”。

一定要使用整数类型进行金钱计算。
这一点再怎么强调也不过分,因为乍一看,浮点类型似乎就足够了

下面是python代码中的一个示例:

>>> amount = float(100.00) # one hundred dollars
>>> print amount
100.0
>>> new_amount = amount + 1
>>> print new_amount
101.0
>>> print new_amount - amount
>>> 1.0
看起来很正常

现在用
10^20
津巴布韦元再试一次:

>>> amount = float(1e20)
>>> print amount
1e+20
>>> new_amount = amount + 1
>>> print new_amount
1e+20
>>> print new_amount-amount
0.0
正如你所见,美元消失了

如果使用integer类型,它可以正常工作:

>>> amount = int(1e20)
>>> print amount
100000000000000000000
>>> new_amount = amount + 1
>>> print new_amount
100000000000000000001
>>> print new_amount - amount
1

十进制表示精确值。Double表示近似值

USD: $12,345.67 USD (Decimal)
CAD: $13,617.27 (Decimal)
Exchange Rate: 1.102932 (Double)
我的问题是a什么时候应该使用a double,我应该在什么时候使用十进制 类型

decimal
用于处理10^(+/-28)范围内的值时,以及基于基本10表示法对行为有期望时-基本上是金钱

double
适用于需要相对精度(即大值的尾随数字精度不存在问题)的情况,适用于大幅度差异-
double
覆盖范围超过10^(+/-300)。科学计算就是最好的例子

哪种类型适合货币 计算

十进制,十进制,十进制

不接受替代品

最重要的因素是,作为二进制分数实现的
double
,根本无法准确表示许多
十进制分数(如0.1),其总位数较小,因为它是64位宽,而
十进制分数是128位。最后,金融应用程序通常必须遵循特定的规则(有时是法律规定的)<代码>十进制
<代码>双精度
没有。

/-7位数字
/-15-16位数字
/-28-29位有效数字

我被错误的类型(几年前)刺痛的方式是大量使用:

  • 520532.52英镑-8位数
  • 1323523.12英镑-9位数
你以100万的价格买了一辆车

15位货币值:

  • 1234567890123.45英镑
9万亿加上一个双倍的数字。但是除法和比较更复杂(我绝对不是浮点和无理数方面的专家)。小数和双精度混合会导致以下问题:

数学运算或比较运算 使用浮点数的 如果 使用十进制数是因为 浮点数可能不是 精确地逼近小数点 号码

有一些类似的更深入的答案


在货币应用程序中使用
double
而不是
decimal
是一种微观优化——这是我看待它的最简单的方式。

我认为除了位宽度之外的主要区别是decimal的指数基数为10,double的指数基数为2


您想要分的分数吗?(就像在加油站一样)实际上有一个相当好的答案:decimal的工作原理类似于long和int(它是一种整数类型!),但它的语法和输出格式中有一个点(请参阅)。Double和float使用尾数和指数(请参阅)。就是这样。看这个链接:并不是说double不准确——它有相对的精度,可以表示十进制根本无法处理的非常大或非常小的量值。这就是为什么使用十进制表示货币:double的精度只有16位十进制数字,经过几次算术运算后,错误将很快累积到足够大的数值,可以爬到15、14、13等数字。四舍五入到“美分”要求在美分数字后至少有一个完全准确的数字,但实际上,您应该保留4或5以避免累积的算术错误,您不能允许损坏用于四舍五入美分的第一百列。这就给你留下了16(总计)-2(美分)-(4或5个错误填充)=哦$hit对于你的钱来说只有7(或更少)个可靠的整数位数!因此,我不会操纵超过9.99美元(1个整数)的货币值,因为我想要的不是4或5位数的错误累积填充,而是10或11。因为十进制是一个128位的数字,所以它给了你这种隔离,即使数字有数百万亿美元,因为它有28-29位的准确度。然而,你不能再高了。999999999999999.99R(999万亿)需要18位精度才能正确四舍五入,因为十进制数为28-29,这仅仅是10位累积算术错误隔离。只需将其磨合一下。。。如果你正在制作一个游戏,你真的会在乎你刚刚弹射过一个四分之一英里的炸药桶是否因为数百个“位置+(速度*时间)”步数的累积误差而偏离目标1/16英寸?我对此表示怀疑。要澄清这一点,double没有16位数字——那只是有意义的数字。浮点数是以基数2数学中的指数为基础的-在二进制浮点数数学
0.1*0.1!=0.01
,因为0.1无法准确表示。数学运算