math.floor(N)vs N // 1

时间:2016-06-03 15:45:40

标签: python math floor

我想知道是否有人可以在 Python3 中了解以下内容的相同/不同之处:

N // 1

from math import floor
floor(N)

我尝试了以下内容,这似乎表明它们是等效的:

import math
import random

for _ in range(0, 99999):
    f = random.random()
    n = random.randint(-9999, 9999)
    N = f * n
    n_div = N // 1; n_mth = math.floor(N)
    if n_div != n_mth:
        print("N // 1: {} | math.floor(N): {}".format(n_div, n_mth))
else: # yes, I realize this will always run
    print("Seem the same to me")

感谢下面的评论。更新了以下测试,清楚地显示float // N返回float,而math.floor(N)返回python3中的int 。据我了解,这种行为在 python2 中有所不同,其中math.ceilmath.floor返回float s。

另请注意在math.ceil而不是math.floor上使用intfloat是多么不寻常/愚蠢:在{{1}上运行的任一函数只需返回int

int

3 个答案:

答案 0 :(得分:5)

使用花车时你会发现差异:

>>> 1000.5//1
1000.0
>>> floor(1000.5)
1000

floor返回一个整数。对于大多数情况,10001000.0是等效的,但并非总是如此。

答案 1 :(得分:3)

  1. math.floor(N)返回一个int,N // 1返回一个浮点数。

    >>> type(math.floor(-4.4))
    <class 'int'>
    >>> type((-4.4) // 1)
    <class 'float'>
    
  2. 由于此floor(nan)会引发ValueError,而nan // 1会返回NaN(类似于±inf。)

    >>> math.floor(math.nan)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: cannot convert float NaN to integer
    >>> math.nan // 1
    nan
    
  3. 当N是浮点数时,我不认为存在其他差异,因为x//y被定义为⌊x/y⌋。

答案 2 :(得分:2)

math.floor首先尝试使用__floor__魔术方法,如果它不存在,则改为使用__float__,然后将其放置,这样当对象支持时{{1}或者可以转换为__floor__

float使用x//1魔术方法,如果未定义或返回__floordiv__,则会在整数NotImelemeted上尝试__rfloordiv__,这几乎肯定会是1,因此需要在相关对象上实施NotImplemented

__floordiv__

通常情况下,这两个值总是相等,但可能会以不同的方式实现两者,通常唯一值得注意的区别是返回值的类型,尽管可能会有更多根据您使用的对象类型进行更改:

from math import floor

class MyInt(int):
    def __floor__(self):
        print("using __floor__")
        return int.__floor__(self)
    def __floordiv__(self,other):
        print("using __floordiv__")
        return int.__floordiv__(self,other)

>>> x = MyInt(5)
>>> floor(x)
using __floor__
5
>>> x//1
using __floordiv__
5