为啥 1 // 0.1 == 9.0? [复制]

Posted

技术标签:

【中文标题】为啥 1 // 0.1 == 9.0? [复制]【英文标题】:Why does 1 // 0.1 == 9.0? [duplicate]为什么 1 // 0.1 == 9.0? [复制] 【发布时间】:2016-10-01 21:13:18 【问题描述】:

在 Python 2.73.x 中,为什么整数除法在除以数字 0 < x < 1 时会给出不正确的数字?

负数 -1 < x < 0 甚至可以正常工作:

>>> 1//.1
9.0
>>> 1//-.1
-10.0

我知道带有负数(或正数)的整数除法会向负无穷大舍入,但是我认为1//.1 应该导致10.0,因为1 可以除以.1 而没有余数。

【问题讨论】:

楼层划分。看到这个帖子:***.com/questions/5535206/… floor(1/.1) 应该等于 10 可能是Is floating point math broken?的另一个神器 @Gilgamesh 这并不能解释为什么1 // 0.1floor(1 / 0.1) 不一样 @Hurkyl 没有必要 "expect" 任何事情,但是如果1//0.1 != math.floor(1/0.1),这个问题应该得到一个答案,说明原因(或者至少是解释该细节的问题)。 【参考方案1】:

您在这里看到的本质上是使用/ 的“正常”除法和使用// 的地板除法之间的差异的效果。

同样重要的是要记住general issue with floating point arithmetic,这只是因为它们的工作方式而存在一定的不精确性。在这些情况下,最好使用decimal 模块来检查实际情况。所以让我们看看你在这里做什么:

首先,.1 已经不准确了:

>>> Decimal(.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')

那么,让我们看看除法的实际结果:

>>> Decimal(1) / Decimal(.1)
Decimal('9.999999999999999444888487687')
>>> 1 / .1
10.0

如您所见,使用/ 的正常除法并不能完全为您提供带有浮点运算的10。但它真的很接近。这就是为什么当你使用普通浮点数时,你实际上会得到 10(因为除法不精确会立即丢失在数字类型的不精确中)。

当使用地板除法时,结果在不精确被纠正之前被地板化,这就是你得到9的原因:

>>> Decimal(1) // Decimal(.1)
Decimal('9')
>>> 1 / .1
10.0

对于负数,地板效应是相反的方向,正如in that other question 解释的那样:

>>> Decimal(1) / Decimal(-.1)
Decimal('-9.999999999999999444888487687')
>>> 1 / -.1
-10.0
>>> Decimal(1) // Decimal(-.1)
Decimal('-9')
>>> 1 // -.1
-10.0

【讨论】:

另一个很好的例子是3 // -.3,它“失败”为负数,导致-11.0 注意:Decimal("1") // Decimal("0.1") 给出Decimal("10"),因为它可以精确地表示十进制数。 Decimal 精确地保留了给定的数字,因此将字符串提供给 decimal 可能对人工输入更精确

以上是关于为啥 1 // 0.1 == 9.0? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥“x”的值发生了变化? [复制]

为啥 Android Studio 不会在 Android Pie (9.0) 上运行应用程序?

为啥 EmailAddressAttribute.IsValid 和 MailAddress 认为包含“ª”的电子邮件是有效的? [复制]

为啥这个 div margin-top 没有按预期工作? [复制]

在 GHCi 中,为啥函数箭头 `:kind (->)` 的种类包含问号 `(->) :: ?? ->? -> *`? [复制]

HTML:为啥没有本地支持来限制复选框中的状态更改而不禁用它? [复制]