math.floor(N)vs N // 1

Not*_*ner 2 python math floor

我想知道是否有人可以给我任何关于Python3中以下内容可能相同/不同的见解

N // 1
Run Code Online (Sandbox Code Playgroud)

from math import floor
floor(N)
Run Code Online (Sandbox Code Playgroud)

我尝试了以下操作,似乎表明它们是等效的:

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")
Run Code Online (Sandbox Code Playgroud)

感谢您在下面的评论。将测试更新为以下内容,该内容清楚地显示在python3float // N返回float,而math.floor(N)返回。据我了解,此行为在python2中不同,其中where 和return s。int math.ceilmath.floorfloat

同样要注意不同寻常的/傻它是使用math.ceilmath.floorint,而不是一个float:上功能操作要么int简单地返回int

import math
import random

for _ in range(0, 99):
    N = random.uniform(-9999, 9999)
    n_div = N // 1; n_mth = math.floor(N)
    if n_div != n_mth:
        print("N: {} ... N // 1: {} | math.floor(N): {}".format(N, n_div, n_mth))
    elif type(n_div) != type(n_mth):
        print("N: {} ... N // 1: {} ({}) | math.floor(N): {} ({})".format(N, n_div, type(n_div), n_mth, type(n_mth)))
else:
    print("Seem the same to me")
Run Code Online (Sandbox Code Playgroud)

Sim*_*ser 5

使用浮点数时,您会发现不同之处:

>>> 1000.5//1
1000.0
>>> floor(1000.5)
1000
Run Code Online (Sandbox Code Playgroud)

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


ken*_*ytm 5

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

    >>> type(math.floor(-4.4))
    <class 'int'>
    >>> type((-4.4) // 1)
    <class 'float'>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 因为这floor(nan)会在nan // 1返回 NaN时引发 ValueError (类似于 ±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
    
    Run Code Online (Sandbox Code Playgroud)

我认为当 N 是浮点数时没有其他区别,因为它x//y被定义为 ⌊x/y⌋。


Tad*_*sen 5

math.floor首先尝试使用__floor__魔法方法,如果它不存在,它会使用__float__然后将其地板,因此当对象支持__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
Run Code Online (Sandbox Code Playgroud)

通常这两个值总是相等的,但可能以不同的方式实现这两个值,通常唯一显着的区别是返回值的类型,尽管根据您使用的对象类型可能会有更多实质性的变化:

>>> x = numpy.array([1.5, 2.3, 5])
>>> x//1
array([ 1.,  2.,  5.])
>>> floor(x)
Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    floor(x)
TypeError: only length-1 arrays can be converted to Python scalars
Run Code Online (Sandbox Code Playgroud)