2016-06-03 3 views
1

мне интересно, если кто-нибудь может дать мне представление о том, как следующие могут быть одинаковыми/разными в Python3:Math.floor (N) против N // 1

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) возвращает intв python3. Как я понимаю, это поведение отличается от python2, где math.ceil и math.floor return float s.

Также обратите внимание, как необычно/глупо было бы использовать math.ceil или math.floor на условиях int вместо 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") 
+0

Это все равно. –

+0

'//' возвращает 'float' и' floor' возвращает 'int'? –

+0

@tobias_k в Python 3, 'math.float()' и 'math.ceil()' return 'ints' – NotAnAmbiTurner

ответ

4

Вы заметили разницу при использовании поплавков:

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

floor возвращает целое число. В большинстве случаев 1000 и 1000.0 эквивалентны, но не всегда.

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 (аналогично для ± инф.)

    >>> 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 
    

Я не думаю, что есть и другие различия, когда N является плавающей точкой , так как x//y определяется как & llloor; x/y & rfloor ;.

+0

Я думаю, что этот ответ практически правильный, потому что вы можете рассчитывать использовать эти функции только на поплавках. – NotAnAmbiTurner

2

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 

Обычно эти два значения всегда будут равны но могут реализовать два по-разному, как правило, только заметное отличие является тип возвращаемого значения, хотя может быть более существенные изменения, в зависимости от того, какой объект, который вы используете:

>>> 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 
Смежные вопросы