为什么Python的math.ceil()和math.floor()操作返回浮点数而不是整数?

Yar*_*rin 164 python math

有人可以解释这个(直接来自文档 - 强调我的):

math.ceil(x)x的上限返回为float,即大于或等于x 的最小数值.

math.floor(x)x的底限作为float返回,最大数值小于或等于x.

为什么会根据定义计算整数.ceil.floor返回浮点数?


编辑:

好吧,这有一些非常好的论据,为什么他们应该返回浮点数,而我只是习惯了这个想法,当@jcollado指出它们实际上确实在Python 3中返回了它们...

Gre*_*ill 97

浮点数的范围通常超出整数范围.通过返回浮点值,函数可以为位于可表示的整数范围之外的输入值返回合理值.

考虑一下:如果floor()返回一个整数,应该floor(1.0e30)返回什么?

现在,虽然Python的整数现在是任意精度,但并不总是这样.标准库函数是等效C库函数周围的瘦包装器.

  • 即使Python整数现在是任意精度,仍然存在浮点数,其地板和天花板不能用整数表示.尝试`floor(float("inf"))`或`ceil(float("nan"))`. (13认同)
  • @Michael-显然在P3中,如果你尝试,你现在将获得OverflowExceptions.见[jcollado](http://stackoverflow.com/a/8582845/165673)的回答 (4认同)
  • 呃,它应该返回一个'long'类型(又名'bigint'),不应该吗?对我来说似乎是一个明显的答案,但现在我觉得我在某种程度上是天真的. (4认同)
  • @koschei:在Python 3.x中,请参阅jcollado的回答. (3认同)

jco*_*ado 93

正如其他答案所指出的,在python中,他们返回浮点数可能是因为历史原因可以防止溢出问题.但是,它们在python 3中返回整数.

>>> import math
>>> type(math.floor(3.1))
<class 'int'>
>>> type(math.ceil(3.1))
<class 'int'>
Run Code Online (Sandbox Code Playgroud)

您可以在PEP 3141中找到更多信息.

  • 为了完整性,Python的`numpy.floor`和`ceil`返回浮点数(<class'numpy.float64'>) (9认同)
  • @Yarin我刚输入上面的命令.此外,如果你尝试使用`float("inf")`或`float("nan")`,你将得到一个'OverflowError`异常. (4认同)

Cha*_*les 17

因为python的数学库是C数学库的一个薄包装器,它返回浮点数.


Ste*_*non 16

您的评论中可以看出您混淆的根源:

ceil/floor操作的重点是将浮点数转换为整数!

ceil和floor操作的要点是将浮点数据舍入为整数值.不要进行类型转换.需要获取数值的用户可以在操作后进行显式转换.

请注意,如果所有可用的都是返回整数的ceil或float操作,则不可能像往常一样实现舍入到整数值.您需要首先检查输入是否在可表示的整数范围内,然后调用该函数; 您需要在单独的代码路径中处理NaN和无穷大.

此外,如果要符合IEEE 754,则必须具有返回浮点数的ceil和floor版本.

  • 在我多年的编程中,我不记得曾经遇到过我*想要*floor/ceil的结果是浮点而不是整数的情况.python3*返回整数这一事实表明这实际上是更有用的事情.我不买"......的要点"; 似乎你根据它的作用定义了这一点,而不是程序员可能想要的. (12认同)
  • @ShreevatsaR我有几次这种情况(但是,主要是在Python上下文之外).我记得的时候是与Mandelbrot集合合作的时候.有时您需要创建一个整数值,然后立即对该值应用一些浮点运算(比如,将其缩放0.5).然后保持浮动浮点并对其应用浮点运算比首先将其转换为int然后立即将其转换回浮点更有效. (2认同)

Mar*_*som 5

在Python 2.4之前,整数不能保存截断实数的全部范围.

http://docs.python.org/whatsnew/2.4.html#pep-237-unifying-long-integers-and-integers

  • @leftaroundabout - 挑剔挑剔!你知道我的意思. (6认同)
  • 它现在也不能保持"全范围的截断实数",因为这显然是一个无限集,因此需要无限量的内存.它可以保持截断的_floats_的范围,这只是ℝ的一小部分. (2认同)