Python十进制与C#十进制精度

Python十进制与C#十进制精度,python,python-2.7,decimal,Python,Python 2.7,Decimal,我知道这个问题已经被问了很多次,我也在很多博客上找到了答案,但这一个让我感到非常惊讶。我只想把一个两位小数乘以100,所以我去掉了小数: >>> 4321.90 * 100 432189.99999999994 >>> Decimal(4321.90) * Decimal(100) Decimal('432189.9999999999636202119291') 我害怕用舍入来进行这种看似琐碎的操作。安全吗?如果精度问题捉弄了我,结果接近xxx.5怎么办?那

我知道这个问题已经被问了很多次,我也在很多博客上找到了答案,但这一个让我感到非常惊讶。我只想把一个两位小数乘以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的十进制模块应该能够解决这个问题。我将要把初始值转换成字符串,并用字符串操作进行计算,对此我感到很难过…

Python失败的主要原因是
4321.90
被解释为浮点(此时精度会降低),然后在运行时转换为
Decimal
。对于C#
4321.90m
一开始被解释为十进制。Python根本不支持将小数作为内置结构

但是有一种简单的方法可以用Python解决这个问题。只需使用字符串:

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

在Python中失败的主要原因是
4321.90
被解释为浮点型(此时会失去精度),然后在运行时转换为
Decimal
。对于C#
4321.90m
一开始被解释为十进制。Python根本不支持将小数作为内置结构

但是有一种简单的方法可以用Python解决这个问题。只需使用字符串:

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

Decimal(number)
不会改变任何东西:值在到达
Decimal
之前被修改

通过将字符串传递给
十进制
,可以避免这种情况,不过:

Decimal("4321.90") * Decimal("100")
结果:

Decimal('432190.00')
(因此,
Decimal
根本不使用浮点寄存器和操作来处理浮点数)

Decimal(number)
不会改变任何东西:值在到达
Decimal
之前被修改

通过将字符串传递给
十进制
,可以避免这种情况,不过:

Decimal("4321.90") * Decimal("100")
结果:

Decimal('432190.00')
(因此,
Decimal
处理浮点数,而根本不使用浮点寄存器和操作)

我将把初始值转换成字符串

对!!(但不要通过调用
str
-使用字符串文字来实现)

然后用字符串操作进行数学运算

将十进制值硬编码到源代码中时,应该从字符串文本而不是浮点文本初始化它。对于
4321.90
,浮点舍入已经发生,构建小数点并不能撤消这一点。使用
“4321.90”
,Decimal可以使用您编写的原始文本执行精确的初始化:

Decimal('4321.90')
我将把初始值转换成字符串

对!!(但不要通过调用
str
-使用字符串文字来实现)

然后用字符串操作进行数学运算

将十进制值硬编码到源代码中时,应该从字符串文本而不是浮点文本初始化它。对于
4321.90
,浮点舍入已经发生,构建小数点并不能撤消这一点。使用
“4321.90”
,Decimal可以使用您编写的原始文本执行精确的初始化:

Decimal('4321.90')

文本
4321.90
是一个二进制浮点值,无论它出现在什么上下文中。因此,您没有传递您认为要传递给
decimal()
构造函数的十进制值。改为拼写它
Decimal(“4321.90”)
。如果它始终是一个小数点后两位的数字,请将其转换为字符串,并将点“.”替换为零。@Ev.Kounis这是字符串操作,我不想这样做。这个问题是重复的,它确实回答了我在这里面临的根本问题。然而,这个问题让我意识到十进制(4321.90)和十进制('4321.90')之间实际上存在差异,这就引出了上述问题。无论在什么上下文中出现,文本
4321.90
都是二进制浮点。因此,您没有传递您认为要传递给
decimal()
构造函数的十进制值。改为拼写它
Decimal(“4321.90”)
。如果它始终是一个小数点后两位的数字,请将其转换为字符串,并将点“.”替换为零。@Ev.Kounis这是字符串操作,我不想这样做。这个问题是重复的,它确实回答了我在这里面临的根本问题。然而,这个问题让我意识到十进制(4321.90)和十进制('4321.90')之间实际上存在差异,这就引出了上述问题。因此,在所有情况下,初始值都应该是字符串,然后传递给Decimal(),无论它是来自用户输入、数据库查询还是硬编码。对吗?(顺便说一句,我喜欢你的答案。简洁明了)@Jerther确切地说,要安全地(或者更准确地)初始化
Decimal
,你需要字符串。还有Decimal(repr(4321.90))可以很好地实现这一点@不,它不是:
repr(11.00000000000000 1)
'11.00000000000000 2'
。它也面临同样的问题。解析
repr
中的浮点,然后四舍五入到最接近的浮点数。然后在那个号码上调用repr,这个号码与原来的号码不同。对,对不起。据我所知,str()还有另一个行为。因此,在所有情况下,初始值都应该是一个字符串,然后传递给Decimal(),无论它是来自用户输入、数据库查询还是硬编码。对吗?(顺便说一句,我喜欢你的答案。简洁明了)@Jerther确切地说,要安全地(或者更准确地)初始化
Decimal
,你需要字符串。还有Decimal(repr(4321.90))可以很好地实现这一点@不,它不是:
repr(11.00000000000000 1)
'11.00000000000000 2'
。它遭受