Ich habe etwas über den //
Operator in Python herausgefunden, der in Python 3 mit Floor dividiert.
Gibt es einen Operator, der stattdessen mit Ceil teilt? (Ich kenne den /
Operator, der in Python 3 eine Gleitkommadivision durchführt.)
Ich habe etwas über den //
Operator in Python herausgefunden, der in Python 3 mit Floor dividiert.
Gibt es einen Operator, der stattdessen mit Ceil teilt? (Ich kenne den /
Operator, der in Python 3 eine Gleitkommadivision durchführt.)
Antworten:
Es gibt keinen Operator, der mit Ceil teilt. Sie müssen import math
und verwendenmath.ceil
Sie können einfach eine verkehrte Bodenteilung durchführen:
def ceildiv(a, b):
return -(-a // b)
Dies funktioniert, weil der Division-Operator von Python die Floor-Division durchführt (im Gegensatz zu C, wo die Integer-Division den Bruchteil abschneidet).
Dies funktioniert auch mit den großen Ganzzahlen von Python, da keine (verlustbehaftete) Gleitkommakonvertierung erfolgt.
Hier ist eine Demonstration:
>>> from __future__ import division # a/b is float division
>>> from math import ceil
>>> b = 3
>>> for a in range(-7, 8):
... print(["%d/%d" % (a, b), int(ceil(a / b)), -(-a // b)])
...
['-7/3', -2, -2]
['-6/3', -2, -2]
['-5/3', -1, -1]
['-4/3', -1, -1]
['-3/3', -1, -1]
['-2/3', 0, 0]
['-1/3', 0, 0]
['0/3', 0, 0]
['1/3', 1, 1]
['2/3', 1, 1]
['3/3', 1, 1]
['4/3', 2, 2]
['5/3', 2, 2]
['6/3', 2, 2]
['7/3', 3, 3]
int
dies nicht tut (naja, keine aussagekräftigen; bei 64-Bit-Python sind Sie auf Bitnummern beschränkt 30 * (2**63 - 1)
), und selbst das vorübergehende Konvertieren in float
kann zu Informationsverlust führen. Vergleiche math.ceil((1 << 128) / 10)
mit -(-(1 << 128) // 10)
.
Sie tun können , (x + (d-1)) // d
wenn Teilung x
durch d
, dh (x + 4) // 5
.
math.ceil()
.
sys.float_info.max
und es erfordert keinen Import.
def ceiling_division(n, d):
return -(n // -d)
Erinnert an den Penn & Teller-Levitationstrick , stellt dies "die Welt auf den Kopf (mit Negation), verwendet eine einfache Bodenteilung (wo Decke und Boden vertauscht wurden) und dreht dann die Welt mit der rechten Seite nach oben (wieder mit Negation). ""
def ceiling_division(n, d):
q, r = divmod(n, d)
return q + bool(r)
Die Funktion divmod () gibt (a // b, a % b)
für ganze Zahlen an (dies kann bei Floats aufgrund eines Rundungsfehlers weniger zuverlässig sein). Der Schritt mit bool(r)
addiert eins zum Quotienten, wenn ein Rest ungleich Null vorliegt.
def ceiling_division(n, d):
return (n + d - 1) // d
Verschieben Sie den Zähler nach oben, sodass die Bodenteilung auf die vorgesehene Decke abgerundet wird. Beachten Sie, dass dies nur für Ganzzahlen funktioniert.
def ceiling_division(n, d):
return math.ceil(n / d)
Der Code math.ceil () ist leicht zu verstehen, wird jedoch von Ints in Floats und zurück konvertiert. Dies ist nicht sehr schnell und kann zu Rundungsproblemen führen. Außerdem stützt es sich auf die Python 3-Semantik, bei der "true Division" einen Float erzeugt und bei der die Funktion lid () eine Ganzzahl zurückgibt.
-(-a // b)
o_O
Sie können es auch immer einfach inline tun
((foo - 1) // bar) + 1
In Python3 ist dies nur eine Größenordnung schneller als das Erzwingen der Float-Division und das Aufrufen von Ceil (), vorausgesetzt, Sie kümmern sich um die Geschwindigkeit. Was Sie nicht sollten, es sei denn, Sie haben durch die Verwendung bewiesen, dass Sie müssen.
>>> timeit.timeit("((5 - 1) // 4) + 1", number = 100000000)
1.7249219375662506
>>> timeit.timeit("ceil(5/4)", setup="from math import ceil", number = 100000000)
12.096064013894647
number=100000000
). Bei einem einzelnen Anruf ist der Unterschied ziemlich unbedeutend.
foo = -8
und bar = -4
zum Beispiel sollte die Antwort 2 sein, nicht 3, genau wie -8 // -4
. Die Python-Bodenteilung ist definiert als "die mathematische Division mit der auf das Ergebnis angewendeten 'Boden'-Funktion", und die Deckenteilung ist dasselbe, jedoch mit ceil()
statt floor()
.
Beachten Sie, dass math.ceil auf 53 Bit Genauigkeit beschränkt ist. Wenn Sie mit großen Ganzzahlen arbeiten, erhalten Sie möglicherweise keine genauen Ergebnisse.
Die Bibliothek gmpy2 bietet eine c_div
Funktion, die die Deckenrundung verwendet.
Haftungsausschluss: Ich pflege gmpy2.
python2 -c 'from math import ceil;assert ceil(11520000000000000102.9)==11520000000000000000'
(sowie zu ersetzen python3
) BEIDE sindTrue
Einfache Lösung: a // b + 1