Python Decimal vs C#decimal precision

时间:2017-06-28 20:57:00

标签: python python-2.7 decimal

我知道这已经被多次询问了,我遇到过很多博客和SO答案,但是这个让我脱掉了头发。我只想将两位十进制数乘以100,这样我就可以删除它的小数:

>>> 4321.90 * 100
432189.99999999994
>>> Decimal(4321.90) * Decimal(100)
Decimal('432189.9999999999636202119291')

我害怕使用舍入来进行这种看似微不足道的操作。它会安全吗?如果精度问题对我起作用并且结果接近xxx.5怎么办?这会发生吗?我确实理解二进制级别的问题,但我来自C#,我没有.Net的decimal类型的问题:

decimal x = 4321.90m;
decimal y = 100m;
Console.WriteLine(x * y);
432190,00

我认为Python的十进制模块应该可以解决这个问题。我准备将初始值转换为字符串并使用字符串操作进行数学计算,我对此感到不满......

3 个答案:

答案 0 :(得分:4)

它因Python失败的主要原因是因为4321.90被解释为float(你在那时失去了精度),然后在运行时被转换为Decimal。 C#4321.90m被解释为十进制开头。 Python根本不支持小数作为内置结构。

但是使用Python可以轻松解决这个问题。只需使用字符串:

>>> Decimal('4321.90') * Decimal('100')
Decimal('432190.00')

答案 1 :(得分:2)

  

我要将初始值转换为字符串

是的! (但不要通过调用str来执行此操作 - 使用字符串文字)

  

并使用字符串操作进行数学运算

没有!

将十进制值硬编码到源代码中时,应该从字符串文字初始化它,而不是浮点文字。对于4321.90,已经发生了浮点舍入,并且构建一个Decimal不会撤消该舍入。对于"4321.90",Decimal具有您编写的原始文本,可用于执行精确初始化:

Decimal('4321.90')

答案 2 :(得分:1)

Floating point inaccuracy again

Decimal(number)无法更改内容:点击Decimal之前修改了

您可以通过将字符串传递给Decimal来避免这种情况,但是:

Decimal("4321.90") * Decimal("100")

结果:

Decimal('432190.00')

(所以Decimal处理浮点数而不使用浮点寄存器和放大器操作)