Wie rundet man eine Zahl in Python auf?

487

Dieses Problem bringt mich um. Wie rundet man eine Zahl UP in Python auf?

Ich habe versucht, die Zahl abzurunden, aber es hat die Zahl abgerundet. Beispiel:

round(2.3) = 2.0 and not 3, what I would like

Das habe ich versucht int (Nummer + .5) aber es rundet die Nummer wieder ab! Beispiel:

int(2.3 + .5) = 2

Dann habe ich es mit Runde (Nummer + .5) versucht, aber in Randfällen funktioniert es nicht. Beispiel:

WAIT! THIS WORKED!

Bitte beraten.

bodacydo
quelle
4
round(number + .5)funktioniert nicht, wenn die Zahl eine Ganzzahl ist. round(3+.5) == 4, wenn du eigentlich willst 3.
Nearoo

Antworten:

845

Die Deckenfunktion :

import math
print(math.ceil(4.2))
Steve Tjoa
quelle
21
Ausarbeitung: math.ceil gibt die kleinste Ganzzahl zurück, die größer oder gleich dem Eingabewert ist. Diese Funktion behandelt die Eingabe als float (Python hat keine stark typisierten Variablen) und die Funktion gibt einen float zurück. Wenn Sie ein int wollen, können Sie ein int aus dem Rückgabewert konstruieren, dhint(math.ceil(363))
RW Sinnet
9
@Sinnet: Eigentlich könnte man sagen, dass Python stark typisiert ist stackoverflow.com/a/11328980/5069869
Bernhard
1
@TheEspinosa: Ja, Python ist definitiv stark typisiert. Es ist nur so, dass viele Funktionen Fragen zum Typ einiger Parameter stellen und je nach Antwort unterschiedlichen Code ausführen.
Quamrana
12
@RWSinnet Gibt in Python 3 math.ceilein tatsächliches ganzzahliges Objekt zurück, nicht nur ein schwebendes Objekt mit einem ganzzahligen Wert.
Arthur Tacca
Achten Sie auf die Präzision des Schwimmers, da die 10000000 * 0.00136 = 13600.000000000002Decke stark ansteigen kannmath.ceil(10000000 * 0.00136) = 13601.0
Straße
171

Ich weiß, dass diese Antwort für eine Frage von vor einiger Zeit ist, aber wenn Sie keine Mathematik importieren und nur aufrunden möchten, funktioniert dies für mich.

>>> int(21 / 5)
4
>>> int(21 / 5) + (21 % 5 > 0)
5

Der erste Teil wird zu 4 und der zweite Teil wird mit "True" bewertet, wenn ein Rest vorhanden ist, der zusätzlich True = 1 ist. False = 0. Wenn also kein Rest vorhanden ist, bleibt die gleiche Ganzzahl erhalten, aber wenn ein Rest vorhanden ist, wird 1 hinzugefügt.

user3074620
quelle
38
Nett. Sie können auch //für die Ganzzahldivision verwenden, so dass dies wird 21 // 5 + (21 % 5 > 0).
naught101
6
Dies ist die beste Lösung, wenn nur Ganzzahlen beteiligt sind. Keine unnötigen floats. Nett.
Nico Schlömer
158

Interessantes Python 2.x-Problem:

>>> import math
>>> math.ceil(4500/1000)
4.0
>>> math.ceil(4500/1000.0)
5.0

Das Problem ist, dass das Teilen von zwei Ints in Python ein weiteres Int erzeugt und dieses vor dem Deckenaufruf abgeschnitten wird. Sie müssen einen Wert als Float (oder Cast) festlegen, um ein korrektes Ergebnis zu erhalten.

In Javascript führt genau derselbe Code zu einem anderen Ergebnis:

console.log(Math.ceil(4500/1000));
5
TrophyGeek
quelle
44
In Python 2.x : int / int -> int und int / float -> float In Python 3.x : int / int kann zu einem float
gecco
7
Sie können Python 3.x zum Verhalten in bestimmten Versionen von Python 2.x erhalten, indem Sie "True Division" aktivieren, wie hier
Rob Dennis
110

Wenn Sie mit ganzen Zahlen arbeiten, besteht eine Möglichkeit zum Aufrunden darin, die Tatsache auszunutzen, dass abgerundet wird //: Teilen Sie einfach die negative Zahl und negieren Sie dann die Antwort. Kein Import, Gleitkomma oder Bedingung erforderlich.

rounded_up = -(-numerator // denominator)

Zum Beispiel:

>>> print(-(-101 // 5))
21
David Bau
quelle
1
Was ist, wenn Sie keine mathematische Operation ausführen müssen? Dh du hast nur eine Nummer.
Klik
2
@Klik: dann kannst du einfach durch 1 ==> - (-num // 1) teilen und du bekommst deine Antwort :-) Einen schönen Tag noch! David Bau: sehr schöner Vorschlag!
Marco smdm
10
Ich habe alle Antworten hier zeitlich festgelegt und dies war fünfmal schneller als das nächstbeste (math.ceil). @ Andreas hatte die gleiche Zeit
Mini Totent
@minitotent Das ist nicht überraschend, da es sich um eine einfache Ganzzahldivision und einige Einzelzyklusoperationen handelt. Dies ist die Art von Antwort, die Ihnen einen Job verschafft: Sie verstehen nicht nur die Sprache, sondern alle darunter liegenden Abstraktionsebenen.
Nearoo
Nett! Ich habe immer verwendet (num + den - 1) // den, was für intEingaben mit positiven Nennern in Ordnung ist , aber fehlschlägt, wenn auch nur ein einziges Nicht-Integral floatbeteiligt ist (entweder Zähler oder Nenner); Dies sieht magischer aus, funktioniert aber sowohl für ints als auch für floats. Für kleine Zähler ist es auch schneller (unter CPython 3.7.2). Seltsamerweise ist Ihr Ansatz langsamer, wenn nur der Zähler groß genug ist, um Array-basierte Mathematik zu benötigen. nicht klar, warum dies so ist, da die Teilungsarbeit ähnlich sein sollte und zwei unäre Negationen billiger sein sollten als Addition + Subtraktion.
ShadowRanger
56

Das könnte dir auch gefallen:

>>> import numpy as np
>>> np.ceil(2.3)
3.0

Ich sage nicht, dass es besser ist als Mathe, aber wenn Sie numpy bereits für andere Zwecke verwendet haben, können Sie Ihren Code konsistent halten.

Jedenfalls nur ein Detail, auf das ich gestoßen bin. Ich benutze viel Numpy und war überrascht, dass es nicht erwähnt wurde, aber natürlich funktioniert die akzeptierte Antwort einwandfrei.

Lisa
quelle
3
Numpy zu benutzen ist auch schön. Am einfachsten wäre es mit Mathematik, da es bereits Teil von Python ist, das in Bibliotheken eingebaut ist. Es macht mehr Sinn. Stattdessen, wie Sie bereits erwähnt haben, ist es sinnvoll und konsistent, numpy.ceil zu verwenden, wenn Sie für andere Probleme viel numpy verwenden :-) Guter Hinweis!
Marco smdm
30

Verwenden Siemath.ceil zum Aufrunden:

>>> import math
>>> math.ceil(5.4)
6.0

HINWEIS : Der Eingang sollte float sein.

Wenn Sie eine Ganzzahl benötigen, rufen Sie diese intauf, um sie zu konvertieren:

>>> int(math.ceil(5.4))
6

Übrigens, verwenden Sie math.floor, um abzurunden und roundauf die nächste ganze Zahl zu runden.

>>> math.floor(4.4), math.floor(4.5), math.floor(5.4), math.floor(5.5)
(4.0, 4.0, 5.0, 5.0)
>>> round(4.4), round(4.5), round(5.4), round(5.5)
(4.0, 5.0, 5.0, 6.0)
>>> math.ceil(4.4), math.ceil(4.5), math.ceil(5.4), math.ceil(5.5)
(5.0, 5.0, 6.0, 6.0)
kennytm
quelle
1
Die Eingabe muss nicht unbedingt ein Float sein, wenn Python 3 verwendet wird: ceil() wird sich intern
darum
12

Die Syntax ist möglicherweise nicht so pythonisch, wie man es gerne hätte, aber es ist eine leistungsstarke Bibliothek.

https://docs.python.org/2/library/decimal.html

from decimal import *
print(int(Decimal(2.3).quantize(Decimal('1.'), rounding=ROUND_UP)))
NuclearPeon
quelle
11

Ich bin überrascht, dass niemand vorgeschlagen hat

(numerator + denominator - 1) // denominator

für ganzzahlige Division mit Aufrundung. War früher der übliche Weg für C / C ++ / CUDA (vgl. divup)

Andreas Schuh
quelle
2
Nur für statisch typisierte Sprachen relevant. Wenn der Nenner ein Schwimmer ist, sind Sie tot.
Bharel
Dies funktioniert auch nur dann konsistent, wenn der Nenner positiv ist; Wenn der Nenner negativ ist, müssen Sie ihn addieren, 1anstatt ihn zu subtrahieren, oder die Vorzeichen von Zähler und Nenner umdrehen, bevor Sie die Mathematik durchführen.
ShadowRanger
7

Stellen Sie sicher, dass der gerundete Wert schwebend sein sollte

a = 8 
b = 21
print math.ceil(a / b)
>>> 0

aber

print math.ceil(float(a) / b)
>>> 1.0
Alexey
quelle
6

Versuche dies:

a = 211.0
print(int(a) + ((int(a) - a) != 0))
user3712978
quelle
1
Klug. Der ((int(a) - a) != 0)Ausdruck wird 1immer dann zurückgegeben a, wenn er aufgerundet werden muss. Vielleicht möchten Sie Ihre Antwort erweitern und erklären, wie dies funktioniert.
Tom Aranda
@ TomAranda Kann jemand erklären, wie ein boolescher Ausdruck einen Wert ergibt?
Bowen Liu
6
>>> def roundup(number):
...     return round(number+.5)
>>> roundup(2.3)
3
>>> roundup(19.00000000001)
20

Diese Funktion erfordert keine Module.

PonasM
quelle
Was ist, wenn Ihre Nummer ist 3, dann würde es 4
aufrunden,
15
Dies funktioniert nur in 99% aller Fälle. Du hast das nicht richtig durchdacht. Solche Lösungen sollten unter allen Umständen vermieden werden.
Nearoo
Also statt +.5 + .49999999 gut genug für mich.
FlyingZebra1
5

Die obigen Antworten sind richtig, aber das Importieren des mathModuls nur für diese eine Funktion fühlt sich für mich normalerweise wie ein Overkill an. Zum Glück gibt es noch einen anderen Weg:

g = 7/5
g = int(g) + (not g.is_integer())

Trueund Falsewerden als 1und 0in einer Anweisung mit Zahlen in Python interpretiert . g.is_interger()im Grunde übersetzt zu g.has_no_decimal()oder g == int(g). So lautet die letzte Aussage auf Englisch round g down and add one if g has decimal.

Nearoo
quelle
1
Und wenn Sie Lust haben, können Sie int(g) + (g % 1 > 0)stattdessen verwenden ;-)
Nearoo
from math import ceilscheint das Importieren des gesamten Mathematikmoduls zu beheben :)
SH7890
@ SH7890 Ich fürchte, diese Linie unterscheidet sich nicht wesentlich import mathvon dem, was hinter den Kulissen passiert. Es werden nur alle Symbole außer gelöscht ceil.
Nearoo
5

Ohne Mathematik zu importieren // mit grundlegender Umgebung:

a) Methode / Klassenmethode

def ceil(fl): 
  return int(fl) + (1 if fl-int(fl) else 0)

def ceil(self, fl): 
  return int(fl) + (1 if fl-int(fl) else 0)

b) Lambda:

ceil = lambda fl:int(fl)+(1 if fl-int(fl) else 0)
Kuřátko Zvyk
quelle
5

Für diejenigen, die aufrunden a / bund eine ganze Zahl erhalten möchten :

Eine andere Variante mit ganzzahliger Division ist

def int_ceil(a, b):
    return (a - 1) // b + 1

>>> int_ceil(19, 5)
4
>>> int_ceil(20, 5)
4
>>> int_ceil(21, 5)
5
Pavel
quelle
3

Falls jemand auf eine bestimmte Dezimalstelle aufrunden möchte:

import math
def round_up(n, decimals=0):
    multiplier = 10 ** decimals
    return math.ceil(n * multiplier) / multiplier
osuwireless
quelle
1

Ich bin überrascht round(x + 0.4999), dass ich diese Antwort noch nicht gesehen habe , also werde ich sie ablegen. Beachten Sie, dass dies mit jeder Python-Version funktioniert. Änderungen am Python-Rundungsschema haben die Sache schwierig gemacht. Siehe diesen Beitrag .

Ohne zu importieren, benutze ich:

def roundUp(num):
    return round(num + 0.49)

testCases = list(x*0.1 for x in range(0, 50))

print(testCases)
for test in testCases:
    print("{:5.2f}  -> {:5.2f}".format(test, roundUp(test)))

Warum das so ist

Aus den Dokumenten

Für die eingebauten Typen, die round () unterstützen, werden die Werte auf das nächste Vielfache von 10 zur Potenz minus n gerundet. Wenn zwei Vielfache gleich nahe beieinander liegen, wird auf die gerade Wahl gerundet

Daher wird 2,5 auf 2 und 3,5 auf 4 gerundet. Wenn dies nicht der Fall wäre, könnte das Aufrunden durch Hinzufügen von 0,5 erfolgen, aber wir möchten vermeiden, auf den halben Punkt zu gelangen. Wenn Sie also 0,4999 hinzufügen, werden Sie nah dran sein, aber mit genügend Spielraum, um auf das gerundet zu werden, was Sie normalerweise erwarten würden. Dies wird natürlich fehlschlagen, wenn das x + 0.4999gleich ist [n].5000, aber das ist unwahrscheinlich.

Klik
quelle
2
Bei Verwendung von 0,4999 wird kein korrektes Ergebnis für Eingaben zwischen ???. 0000 und ???. 0001 (offenes Intervall) geliefert, nicht nur genau ???. 0001. Wenn Sie es beispielsweise mit 3.00005 versuchen, erhalten Sie ein Ergebnis von 3 anstelle der erwarteten 4. Natürlich können Sie die Wahrscheinlichkeit verringern, dass dies geschieht, indem Sie mehr und mehr Ziffern bis zur maximalen Genauigkeit von Floats hinzufügen, aber was ist das? darauf hinweisen, wenn es robustere und intuitivere Lösungen gibt, wie z math.ceil().
Blubberdiblub
@blubberdiblub In meiner Antwort gebe ich an Without importing I use:. Ich habe auch erwähnt, dass es fehlschlagen wird, wenn das x + 0.4999gleich ist [n].5000.
Klik
4
Ja, Sie geben in Ihrer Antwort an, dass Ihre Lösung nicht importiert werden kann, aber ich sehe den Wert nicht. Das mathModul math.ceil()befindet sich in der Standardbibliothek und ist somit für alle praktischen Zwecke überall verfügbar, ohne dass zusätzliche Informationen installiert werden müssen. Und in Bezug auf Ihre Erwähnung, wann es fehlschlägt, ist dies in Ihrer Antwort unvollständig, da es für ein ganzes Intervall fehlschlägt, nicht nur für einen einzelnen Punkt. Technisch könnte man argumentieren, dass man richtig ist, wie man sagt, wenn und nicht wenn , aber es wird den Eindruck beim Gelegenheitsleser erwecken, dass es weniger wahrscheinlich ist als es wirklich ist.
Blubberdiblub
0

So machen Sie es ohne Import:

>>> round_up = lambda num: int(num + 1) if int(num) != num else int(num)
>>> round_up(2.0)
2
>>> round_up(2.1)
3
Gorttar
quelle
0

Ich weiß, dass dies schon eine ganze Weile her ist, aber ich habe eine ziemlich interessante Antwort gefunden.

-round(-x-0.5)

Dies behebt die Kantenfälle und funktioniert sowohl für positive als auch für negative Zahlen. Es ist kein Funktionsimport erforderlich

Prost

Fenmaz
quelle
2
Dies wird immer noch -round(-x-0.3) = x
Diblo Dk
0

Wenn Sie 4500/1000 in Python betreiben, ist das Ergebnis 4, da für das Standard-Python-Asume als Ganzzahl das Ergebnis logisch lautet: 4500/1000 = 4,5 -> int (4,5) = 4 und die Obergrenze von 4 ist offensichtlich 4

Bei Verwendung von 4500 / 1000.0 beträgt das Ergebnis 4,5 und die Obergrenze 4,5 -> 5

Wenn Sie Javascript verwenden, erhalten Sie 4.5 als Ergebnis von 4500/1000, da Javascript nur das Ergebnis als "numerischen Typ" annimmt und ein Ergebnis direkt als float zurückgibt

Viel Glück!!

erick vicente
quelle
Das gilt nur für Python 2.x. In Python 3 führt die Division mit einer einzelnen /immer zu einem Float, also 4500/1000immer zu 4,5.
Nearoo
0

Wenn Sie nichts importieren möchten, können Sie jederzeit Ihre eigene einfache Funktion schreiben als:

def RoundUP(num): if num== int(num): return num return int(num + 1)

Sebin
quelle
2
Dies funktioniert nicht, wenn num 2,05 ist. Sie müssen mindestens so viele Ziffern mit einer 9 wie Ihre Eingabe haben, sodass Sie eine 0,999 haben ... das ist 1. Dann wird Ihr Eckfall 2 erneut aufgerundet. - Nun, ich denke, es gibt einen Grund, warum math.ceil da ist.
Johannes Maria Frank
-1

Sie können Floor Devision verwenden und 1 hinzufügen. 2,3 // 2 + 1

user6612280
quelle
2
oder verwenden Sie, ceil()anstatt seltsam das Gegenteil zu tun und dann zu kompensieren
Guival
2
Das wird nicht funktionieren. Zum Beispiel:from math import ceil; assert 4 // 2 + 1 == ceil(4 / 2)
Carl Thomé
-1

Ich denke, Sie verwechseln die Arbeitsmechanismen zwischen int()und round().

int()schneidet die Dezimalzahlen immer ab, wenn eine schwebende Zahl angegeben wird; wohingegen round()im Fall , 2.5wo2 und 3sind beide in gleichem Abstand von 2.5, Python kehrt je nachdem , was das ist mehr entfernt von dem 0 - Punkt.

round(2.5) = 3
int(2.5) = 2
SooBin Kim
quelle
"Aufrunden" bedeutet, dass zB in 2.3verwandelt wird 3, was in keinem Ihrer Beispiele vorkommt.
Nearoo
-2

Mein Anteil

Ich habe getestet print(-(-101 // 5)) = 21 das obige Beispiel oben .

Nun zur Zusammenfassung:

101 * 19% = 19.19

Ich kann nicht verwenden, **also verteile ich die Multiplikation auf Division:

(-(-101 //(1/0.19))) = 20
andres
quelle
-3

Ich bin im Grunde ein Anfänger bei Python, aber wenn Sie nur versuchen, aufzurunden statt abzurunden, warum nicht:

round(integer) + 1
Daniel
quelle
2
Dies funktioniert nicht für eine ganze Zahl i, bei der 2,5 <ganze Zahl <3 ist. Der gewünschte Wert nach dem Aufrunden ist 3, aber Ihr Ausdruck verwandelt ihn in 4.
Pranav Shukla
1
Ich denke du meinst round(integer + 0.5)Das ist was ich oft mache
Klik