Python十进制与C#十进制精度
我知道这个问题已经被问了很多次,我也在很多博客上找到了答案,但这一个让我感到非常惊讶。我只想把一个两位小数乘以100,所以我去掉了小数: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怎么办?那
>>> 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'
。它遭受