为啥 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.7
和 3.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.1
与floor(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? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Android Studio 不会在 Android Pie (9.0) 上运行应用程序?
为啥 EmailAddressAttribute.IsValid 和 MailAddress 认为包含“ª”的电子邮件是有效的? [复制]
为啥这个 div margin-top 没有按预期工作? [复制]
在 GHCi 中,为啥函数箭头 `:kind (->)` 的种类包含问号 `(->) :: ?? ->? -> *`? [复制]