Scheint, das hätte schon hunderte Male gefragt werden sollen (Wortspiel macht Spaß =), aber ich kann nur eine Funktion zum Runden von Schwimmern finden. Wie runde ich eine ganze Zahl auf, zum Beispiel : 130 -> 200
?
Scheint, das hätte schon hunderte Male gefragt werden sollen (Wortspiel macht Spaß =), aber ich kann nur eine Funktion zum Runden von Schwimmern finden. Wie runde ich eine ganze Zahl auf, zum Beispiel : 130 -> 200
?
Antworten:
Das Runden erfolgt normalerweise mit Gleitkommazahlen. Hier sollten Sie drei grundlegende Funktionen kennen: round
(auf die nächste Ganzzahl runden), math.floor
(immer abrunden) und math.ceil
(immer aufrunden).
Sie fragen nach ganzen Zahlen und runden auf Hunderte auf, aber wir können immer noch verwenden math.ceil
, solange Ihre Zahlen kleiner als 2 53 sind . Zur Verwendung math.ceil
teilen wir einfach zuerst durch 100, runden auf und multiplizieren danach mit 100:
>>> import math
>>> def roundup(x):
... return int(math.ceil(x / 100.0)) * 100
...
>>> roundup(100)
100
>>> roundup(101)
200
Wenn Sie zuerst durch 100 dividieren und anschließend mit 100 multiplizieren, werden zwei Dezimalstellen nach rechts und links verschoben, sodass math.ceil
Hunderte funktionieren. Sie können 10**n
anstelle von 100 auch verwenden, wenn Sie auf Zehner ( n = 1
), Tausender ( n = 3
) usw. runden möchten .
Eine alternative Möglichkeit besteht darin, Gleitkommazahlen zu vermeiden (sie haben eine begrenzte Genauigkeit) und stattdessen nur Ganzzahlen zu verwenden. Ganzzahlen haben in Python eine beliebige Genauigkeit, sodass Sie Zahlen beliebiger Größe runden können. Die Regel für das Runden ist einfach: Finden Sie den Rest nach der Division mit 100 und addieren Sie 100 minus diesen Rest, wenn er nicht Null ist:
>>> def roundup(x):
... return x if x % 100 == 0 else x + 100 - x % 100
Dies funktioniert für Zahlen jeder Größe:
>>> roundup(100)
100
>>> roundup(130)
200
>>> roundup(1234567891234567891)
1234567891234567900L
Ich habe einen Mini-Benchmark der beiden Lösungen durchgeführt:
$ python -m timeit -s 'import math' -s 'x = 130' 'int(math.ceil(x/100.0)) * 100'
1000000 loops, best of 3: 0.364 usec per loop
$ python -m timeit -s 'x = 130' 'x if x % 100 == 0 else x + 100 - x % 100'
10000000 loops, best of 3: 0.162 usec per loop
Die reine ganzzahlige Lösung ist im Vergleich zur math.ceil
Lösung um den Faktor zwei schneller .
Thomas schlug eine ganzzahlige Lösung vor, die mit der oben beschriebenen identisch ist, außer dass sie einen Trick durch Multiplizieren von Booleschen Werten verwendet. Es ist interessant zu sehen, dass es keinen Geschwindigkeitsvorteil gibt, den Code so zu schreiben:
$ python -m timeit -s 'x = 130' 'x + 100*(x%100>0) - x%100'
10000000 loops, best of 3: 0.167 usec per loop
Lassen Sie mich abschließend noch bemerken, dass die eingebaute Funktion dies für Sie tun kann , wenn Sie 101–149 auf 100 und 150–199 auf 200 runden wollten, z. B. auf die nächsten hundert runden möchten round
:
>>> int(round(130, -2))
100
>>> int(round(170, -2))
200
math.ceil
ist der kanonische Weg, dies zu tun - Teilen und Multiplizieren mit 100 ist der kanonische Weg round
,ceil
und die floor
Arbeit an Hunderten.
float
Vergleich zu long
(natürlich!) Eine begrenzte Präzision gibt , aber für die meisten praktischen Situationen float
ist a ziemlich groß.
Dies ist eine späte Antwort, aber es gibt eine einfache Lösung, die die besten Aspekte der vorhandenen Antworten kombiniert: Das nächste Vielfache von 100
bis x
ist x - x % -100
(oder wenn Sie es vorziehen x + (-x) % 100
).
>>> x = 130
>>> x -= x % -100 # Round x up to next multiple of 100.
>>> x
200
Dies ist schnell und einfach, liefert korrekte Ergebnisse für jede ganze Zahl x
(wie die Antwort von John Machin) und liefert auch vernünftige Ergebnisse (modulo die üblichen Vorbehalte bezüglich der Gleitkommadarstellung), wenn x
es sich um ein Gleitkomma handelt (wie die Antwort von Martin Geisler).
>>> x = 0.1
>>> x -= x % -100
>>> x
100.0
Versuche dies:
int(round(130 + 49, -2))
Hier ist eine allgemeine Methode zum Aufrunden auf das nächste Vielfache einer positiven Ganzzahl:
def roundUpToMultiple(number, multiple):
num = number + (multiple - 1)
return num - (num % multiple)
Beispielnutzung:
>>> roundUpToMultiple (101, 100) 200 >>> roundUpToMultiple (654, 321) 963
lambda number, multiple: multiple * (1 + (number - 1) // multiple)
Für a
nicht negativ, b
positiv, beide ganzen Zahlen:
>>> rup = lambda a, b: (a + b - 1) // b * b
>>> [(x, rup(x, 100)) for x in (199, 200, 201)]
[(199, 200), (200, 200), (201, 300)]
Aktualisieren Die aktuell akzeptierte Antwort fällt mit ganzen Zahlen auseinander, sodass float (x) / float (y) nicht genau als a dargestellt werden kann float
. Siehe diesen Code:
import math
def geisler(x, y): return int(math.ceil(x / float(y))) * y
def orozco(x, y): return x + y * (x % y > 0) - x % y
def machin(x, y): return (x + y - 1) // y * y
for m, n in (
(123456789123456789, 100),
(1234567891234567891, 100),
(12345678912345678912, 100),
):
print; print m, "m"; print n, "n"
for func in (geissler, orozco, machin):
print func(m, n), func.__name__
Ausgabe:
123456789123456789 m
100 n
123456789123456800 geisler
123456789123456800 orozco
123456789123456800 machin
1234567891234567891 m
100 n
1234567891234568000 geisler <<<=== wrong
1234567891234567900 orozco
1234567891234567900 machin
12345678912345678912 m
100 n
12345678912345680000 geisler <<<=== wrong
12345678912345679000 orozco
12345678912345679000 machin
Und hier sind einige Timings:
>\python27\python -m timeit -s "import math;x =130" "int(math.ceil(x/100.0))*100"
1000000 loops, best of 3: 0.342 usec per loop
>\python27\python -m timeit -s "x = 130" "x + 100 * (x % 100 > 0) - x % 100"
10000000 loops, best of 3: 0.151 usec per loop
>\python27\python -m timeit -s "x = 100" "(x + 99) // 100 * 100"
10000000 loops, best of 3: 0.0903 usec per loop
I know the OP was about rounding an integer
- aber ich wollte darauf hinweisen, dass Sie versuchen würden, diese 3 Optionen für (0.5,10) zu verwenden, von denen ich erwarten würde, dass sie 10 zurückgeben, dann geben die ersten beiden Methoden (geisler & orozco) wie erwartet 10 zurück, während
Wenn Ihr int x ist: x + 100 - x % 100
Wie in den Kommentaren angegeben, gibt dies jedoch 200 zurück, wenn x==100
.
Wenn dies nicht das erwartete Verhalten ist, können Sie verwenden x + 100*(x%100>0) - x%100
bool
hat einen numerischen Wert, also können Sie mit einem booleschen Ausdruck multiplizieren. Die anderen Lösungen sind jedoch klarer.
Versuche dies:
import math
def ceilm(number,multiple):
'''Returns a float rounded up by a factor of the multiple specified'''
return math.ceil(float(number)/multiple)*multiple
Beispielnutzung:
>>> ceilm(257,5)
260
>>> ceilm(260,5)
260
Warnung: Vorzeitige Optimierungen voraus ...
Da so viele der Antworten hier den Zeitpunkt dafür bestimmen, wollte ich eine weitere Alternative hinzufügen.
Nehmen Sie @Martin Geislers
def roundup(x):
return x if x % 100 == 0 else x + 100 - x % 100
(was mir aus mehreren Gründen am besten gefällt)
aber die% Aktion herausrechnen
def roundup2(x):
x100= x % 100
return x if x100 == 0 else x + 100 - x100
Ergibt eine Geschwindigkeitsverbesserung von ~ 20% gegenüber dem Original
def roundup3(x):
x100 = x % 100
return x if not x100 else x + 100 - x100
Ist noch besser und ~ 36% schneller als das Original
Schließlich dachte ich, ich könnte den not
Operator fallen lassen und die Reihenfolge der Zweige ändern, in der Hoffnung, dass dies auch die Geschwindigkeit erhöhen würde, war aber verblüfft, als ich herausfand, dass es tatsächlich langsamer ist, zurückzufallen und nur 23% schneller als das Original zu sein.
def roundup4(x):
x100 = x % 100
return x + 100 - x100 if x100 else x
>python -m timeit -s "x = 130" "x if x % 100 == 0 else x + 100 - x % 100"
1000000 loops, best of 3: 0.359 usec per loop
>python -m timeit -s "x = 130" "x100 = x % 100" "x if x100 == 0 else x + 100 - x100"
1000000 loops, best of 3: 0.287 usec per loop
>python -m timeit -s "x = 130" "x100 = x % 100" "x if not x100 else x + 100 - x100"
1000000 loops, best of 3: 0.23 usec per loop
>python -m timeit -s "x = 130" "x100 = x % 100" "x + 100 - x100 if x100 else x"
1000000 loops, best of 3: 0.277 usec per loop
Erklärungen, warum 3 schneller ist als 4, wären sehr willkommen.
Hier ist eine sehr einfache Lösung:
next_hundred = x//100*100+100
Wie funktioniert es?
Einige Beispiele
Ein leicht modifizierter Ansatz rundet 1 ... 100 bis 100, 101 ... 200 bis 200 usw.:
next_hundred = (x-1)//100*100+100