【问题标题】:What's the rationale behind 2.5 // 2.0 returning a float rather than an int in Python 3.x?2.5 // 2.0 在 Python 3.x 中返回 float 而不是 int 背后的基本原理是什么?
【发布时间】:2017-06-01 21:04:40
【问题描述】:

2.5 // 2.0 在 Python 3.x 中返回 float 而不是 int 背后的基本原理是什么? 如果是整数值,为什么不把它放在int 对象中呢?

[编辑]

我正在寻找事实的理由。这样做的理由是什么。还没找到。

[编辑2]

floor 的关系比“楼层划分”一词所暗示的问题更严重!

floor(3.5 / 5.5) == 0(整数)

3.5 // 5.5 == 0.0(浮点数)

这里还不能辨别任何逻辑:(

[编辑3]

来自 PEP238:

在一个 统一模型,整数 1 应该与 浮点数 1.0(不精确除外),以及两者 在所有数字上下文中的行为应该相同。

一切都很好,但是像 Numpy 这样的不重要的库在提供浮点数作为索引时会抱怨,即使它们是不可或缺的。所以“无法区分”还不是现实。花了一些时间寻找与此相关的错误。得知// 的真实性质,我感到非常惊讶。而且从文档中(对我来说)来说并不是那么明显。

由于我对 Python 3.x 的设计相当信任,我想我一定错过了一个非常明显的理由来以这种方式定义 //。但现在我想知道...

【问题讨论】:

  • @SparklePony 这可能是规则,但规则不是理由。我认为这是一个有趣的问题。
  • @SparklePony:很明显这两个参数都是浮点数。这并不意味着输出必须是浮点数。我们已经有 1/2 返回一个浮点数;为什么不让 1.0//2.0 返回一个 int?
  • 让我直截了当地说.../ 是有问题的,因为模棱两可,其结果取决于数字的类型。所以我们修复了 and 添加了一个具有相同(嗯,类似)问题的新运算符。多么迷人……
  • @KarolyHorvath 好吧,结果的 type 取决于输入,但是使用“新”/// 你不会对结果被四舍五入只是因为输入碰巧不再是整数了。

标签: python


【解决方案1】:

// 运算符包含在 PEP 238 中。首先,请注意它不是“整数除法”而是“地板除法”,即从未声称结果将是整数。

来自楼层划分的语义部分:

在所有 Python 数值类型中都将实现楼层划分,并且将具有以下语义

a // b == floor(a/b)

除了结果类型将是在操作之前将 a 和 b 强制转换为的公共类型。

后来:

对于浮点输入,结果是浮点数。例如:

3.5//2.0 == 1.0

这个决定背后的理由没有明确说明(或者我找不到)。但是,它的实现方式与其他数学运算一致(强调我的):

具体来说,如果 a 和 b 属于同一类型,a//b 也将属于该类型。如果输入的类型不同,则首先将它们强制转换为通用类型使用与所有其他算术运算符相同的规则

此外,如果结果会自动转换为 int,那么对于超出整数精度的非常大的浮点数可能会产生奇怪和令人惊讶的结果:

>>> 1e30 // 2.
5e+29
>>> int(1e30 // 2.)
500000000000000009942312419328

【讨论】:

  • PEP 中是否有任何理由做出此决定?如果不是,我们仍然只是指向一个规则,没有解释......
  • @KarolyHorvath 查看我的编辑。我猜主要原因是 (a) 与其他算术运算一致,以及 (b) 不搞大浮点数。
  • “对于超出整数精度的非常大的浮点数的奇怪和令人惊讶的结果” - 反过来。失去精度的是浮点数。整数转换只是通过显示更多位数使精度损失明显。
  • @tobias_k '对所有其他算术运算符使用相同的规则'。也许就是这样。不过,在文档中值得更多关注(除非我遗漏了什么),特别是因为“地板”的行为与“地板划分”不同,而名称表明它们的行为相似。
  • @JacquesdeHooge 奇怪的是:使用新的部门,// 的行为方式是这样,但 / 不再这样做,即使两个参数都是 int 也会产生一个浮点数... 关于 @987654330 @:请注意,这在技术上不是算术运算,而是一个函数。
猜你喜欢
  • 2012-11-26
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多