2016-06-03 18 views
1

Ich frage mich, ob jemand kann mir jeder Einblick, wie die folgenden können gleich/unterschiedlich in sein Python3:Math.floor (N) vs N // 1

N // 1 

und

from math import floor 
floor(N) 

ich habe versucht, die folgende, die dass sie gleichwertig sind, um anzuzeigen, scheint:

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

Danke für die Kommentare unten. Aktualisierter Test zu den folgenden, die deutlich zeigt float // N gibt eine float zurück, während math.floor(N) eine intin python3 zurückgibt. Wie ich es verstehe, ist dieses Verhalten unterschiedlich in python2, wo math.ceil und math.floor zurück float s.

Beachten Sie auch, wie ungewöhnlich/albern es math.ceil oder math.floor auf einem int anstelle eines float zu verwenden wäre: entweder Funktion auf einem int gibt einfach, dass int arbeitet.

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

Es ist alles gleich. –

+0

'//' gibt ein 'float' zurück und' floor' gibt ein 'int' zurück? –

+0

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

Antwort

4

Sie einen Unterschied erkennen, wenn Floats mit:

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

floor gibt eine ganze Zahl ist. Für die meisten Fälle sind 1000 und 1000.0 äquivalent, aber nicht immer.

3
  1. math.floor(N) gibt einen int und N // 1 gibt einen Schwimmer.

    >>> type(math.floor(-4.4)) 
    <class 'int'> 
    >>> type((-4.4) // 1) 
    <class 'float'> 
    
  2. dieser Weil floor(nan) wird Valueerror erhöhen, während nan // 1 kehrt NaN (ähnlich für ± 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 
    

Ich glaube nicht, es gibt auch andere Unterschiede, wenn N ein Schwimmer , da x//y als & lfloor; x/y & rfloor; definiert ist.

+0

Ich denke, diese Antwort ist praktisch richtig, weil Sie erwarten können, diese Funktionen nur auf Floats zu verwenden. – NotAnAmbiTurner

2

math.floor zuerst versucht, die __floor__ magische Methode zu verwenden, wenn es nicht es stattdessen existiert verwendet __float__ und dann Etagen, dass, so wird es funktionieren, wenn das Objekt __floor__ unterstützt oder kann auf ein float gegossen werden.

x//1 verwendet die __floordiv__ magische Methode und wenn das nicht definiert ist, oder gibt NotImelemeted es versucht, dann __rfloordiv__ auf der ganzen Zahl 1 die mit ziemlicher Sicherheit NotImplemented sein, so würde dies __floordiv__ auf das betreffende Objekt implementiert werden.

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 

Normalerweise werden die beiden Werte immer gleich sein wird, kann aber die zwei unterschiedlich implementieren, in der Regel die einzige merkliche Unterschied ist die Typ der Rückgabewert, obwohl es mehr wesentliche Veränderungen sein können, je nachdem, welche Art von Objekt, das Sie verwenden:

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