为啥整数除法产生一个浮点数而不是另一个整数?

Posted

技术标签:

【中文标题】为啥整数除法产生一个浮点数而不是另一个整数?【英文标题】:Why does integer division yield a float instead of another integer?为什么整数除法产生一个浮点数而不是另一个整数? 【发布时间】:2010-11-19 22:57:07 【问题描述】:

考虑一下 Python 中的这种划分:

Python 3.1 (r31:73574, Jun 26 2009, 20:21:35) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 2/2
1.0

这是故意的吗?我强烈记得返回int/int = int 的早期版本。我该怎么办?是否有新的除法运算符或者我必须始终转换?

【问题讨论】:

是的,这就是 3.x 中除法的工作方式。 这是 Python 的创建者发表的一篇关于舍入如何工作的帖子,它与您的问题正交,但我发现它很有趣:python-history.blogspot.com/2010/08/… @hughdbrown 所以这意味着 all python 3 版本? @hughdbrown:是的,PEP 是final,意思是既接受又实施。 如果你做的不是简单的除法,那么转换浮点结果是一个更好的方法。例如,计算 480 // 640 * 320 结果为 0 【参考方案1】:

看看PEP-238:更改除法运算符

// 运算符将可用于明确地请求楼层划分。

【讨论】:

@JonathanSternberg 除了为 python 2.0 编写的所有代码。我觉得 / 和 // 的角色应该颠倒过来以保持向后兼容性。此外,几乎所有其他语言/保留类型。我会更有意义然后 // 自动转换为浮点数,而不是 /. 第二部分(在“Also”之后)是有道理的(与其他语言相似)但关于第一部分,Python 3 的整个 point 是不倒退的与 Python 2 兼容,而是修复了 Python 2 的一系列问题。足够多的人发现 / 的模棱两可足以成为需要在 Python 3 中修复的语言设计“错误”。这可能是有争议的决定,但有足够多的人认为这是正确的决定。把我算在喜欢改变的群体中。很高兴我们都同意不同意。干杯。 :)【参考方案2】:

糟糕,立即找到2//2。这将输出一个 int 而不是 float。

【讨论】:

这似乎不适用于负数。 -1//5 返回 -1,-5//5 返回 -1。 @mschuett:这是意料之中的,与 Python 2 的结果相同。 是的,我做了更多的挖掘工作,也发现了这一点。但是,我想有相当数量的人没有意识到这一点,具体取决于他们来自的语言。 @TylerH 我怀疑在过去 12 年中是否有任何混淆需要您进行编辑? @JonasByström 投票赞成的 cmets 要求澄清并给出澄清不是线索吗?很难看出一个人不会从答案的原始版本中看到明显的改进机会。好的答案提供了解决方案对所述解决方案的解释。读者可能会因为这个答案而使用// 而不是/,并导致依赖于浮点数的代码中断,而没有意识到其中的含义。【参考方案3】:

Python 2.7 和 Python 3 中除法运算符的行为

在 Python 2.7 中:默认情况下,除法运算符将返回整数输出。

要获得双精度结果,请将被除数或除数乘以 1.0。

100/35 => 2 # Expected is 2.857142857142857
(100*1.0)/35 => 2.857142857142857
100/(35*1.0) => 2.857142857142857

在 Python 3 中

// => used for integer output
/ => used for double output

100/35 => 2.857142857142857
100//35 => 2
100.//35 => 2.0    # Floating-point result if the divisor or dividend is real

【讨论】:

顺便说一句,不需要乘以1.0。其中一个数字是浮点数就足够了。例如,100/35.0 = 100.0/35 = 2.857142857142857 // 不是“用于整数输出”。 //floor() 函数对除法结果的结果,如果两个操作数是整数,则反过来产生一个整数,如果其中至少一个是浮点数,则产生一个浮点数,以实现类型一致性。跨度> 【参考方案4】:

接受的答案已经提到PEP 238。我只想为那些对正在发生的事情感兴趣而无需阅读整个 PEP 的人快速了解一下幕后情况。

Python 将 +-*/ 等运算符映射到特殊函数,例如a + b 相当于

a.__add__(b)

关于 Python 2 中的除法,默认情况下只有 / 映射到 __div__,结果取决于输入类型(例如 intfloat)。

Python 2.2 引入了__future__ 功能division,它通过以下方式更改了除法语义(TL;PEP 238 的DR):

/ 映射到 __truediv__ 必须“返回一个合理的近似值 除法的数学结果”(引自 PEP 238) // 映射到 __floordiv__,它应该返回 / 的取底结果

在 Python 3.0 中,PEP 238 的更改成为默认行为,并且 Python 的对象模型中不再有特殊方法 __div__

如果您想在 Python 2 和 Python 3 中使用相同的代码,请使用

from __future__ import division

并坚持 /// 的 PEP 238 语义。

【讨论】:

【参考方案5】:

根据 Python 3 文档,Python 在除以整数时,尽管预期为整数,但仍会生成浮点数。

对于专门打印整数,使用floor division method。 地板除法是四舍五入零并删除小数点。 Represented by //

因此,使用 2//2 而不是 2/2

无论使用 Python 2 还是 Python 3,您也可以从 __future__ 导入除法。

【讨论】:

以上是关于为啥整数除法产生一个浮点数而不是另一个整数?的主要内容,如果未能解决你的问题,请参考以下文章

为啥神经网络输出浮点数而不是整数?

Python中整数运算除法,输出带浮点数

为啥 Kivy 使用浮点数而不是整数?

TypeError:列表索引必须是整数,而不是浮点数

整数与浮点除法 -> 谁负责提供结果?

Python3 大浮点数的停止除法