Eine Gleitkommazahl auf die nächste Ganzzahl runden?


127

Wie der Titel schon sagt, möchte ich eine Gleitkommazahl auf die nächste Ganzzahl abrunden. Wenn es jedoch kein Ganzes ist, möchte ich die Variable IMMER abrunden, unabhängig davon, wie nahe sie an der nächsten Ganzzahl liegt. Gibt es eine Möglichkeit, dies zu tun?


2
Eine mögliche Schwierigkeit besteht darin, dass IEEE-Gleitkommaformate Zahlen darstellen können, die so groß sind, dass die Grandularität größer als 1 ist. Während Sie also x abrunden können, erhalten Sie durch Abrunden von x + 1 nicht das erwartete Ergebnis.
dmckee --- Ex-Moderator Kätzchen

Bitte posten Sie einige Beispiele.
Ashwini Chaudhary

Antworten:


178

Einfach

print int(x)

wird auch funktionieren.


7
int (0,6) = 0 statt 1
Helin Wang

39
@HelinWang Genau darum hat OP gebeten.
Petr Peller

5
Dies scheint der pythonischste Ansatz zu sein.
Gyan Veda

23
Dies funktioniert gut für positive Zahlen, aber negative Zahlen werden aufgerundet:int(-23.3) == 23
Alex Riley

2
und funktioniert nicht für Zahlen außerhalb des ganzzahligen Bereichs wie 600851475143, es wird grundsätzlich einen Speicherfehler kennzeichnen.
Muyide Ibukun

77

Eines davon sollte funktionieren:

import math
math.trunc(1.5)
> 1
math.trunc(-1.5)
> -1
math.floor(1.5)
> 1
math.floor(-1.5)
> -2

14
Die Ausgabe von math.truncist eine Ganzzahl, während die Ausgabe von math.floorein Float ist.
Evedovelli

6
@evedovelli: Nicht mehr wirklich. type(math.floor(1.51)) -> intund type(math.trunc(1.51)) -> intabpython 3.6.0
SKPS

4
Diese Optionen sind expliziter als "int (x)" und daher pythonischer.
Tristan

43
x//1

Der //Bediener gibt das Stockwerk der Abteilung zurück. Da das Teilen durch 1 Ihre Zahl nicht ändert, entspricht dies der Etage, es ist jedoch kein Import erforderlich. Anmerkungen:

  1. Dies gibt einen Float zurück
  2. Dies rundet in Richtung -∞

Schöne Ergänzung. int(-1.1) == -1Während -1.1//1 == -2.0jedoch decimal.Decimal('-1.1')//1 == decimal.Decimal('-1')(wie dokumentiert, Anspruch 2 nicht zutrifft decimal), //ist es auch heute noch nicht vollständig stabil, sich darauf zu verlassen, wie sich das Verhalten verhält.
Tino

28

Um ein Gleitkommaergebnis zu erhalten, verwenden Sie einfach:

round(x-0.5)

Es funktioniert auch für negative Zahlen.


6
extrem raffiniert das ist
Alon


9

Viele Leute sagen zu verwenden int(x), und dies funktioniert in den meisten Fällen in Ordnung, aber es gibt ein kleines Problem. Wenn das Ergebnis von OP ist:

x = 1.9999999999999999

es wird zu runden

x = 2

nach dem 16. 9 wird es rund. Dies ist keine große Sache, wenn Sie sicher sind, dass Sie so etwas nie finden werden. Aber es ist etwas zu beachten.


17
Das liegt daran, dass 1.9999999999999999es tatsächlich gleich 2.0in der internen float64-Darstellung ist. I. e. Es wird bereits gerundet, sobald es in einen Float analysiert wird, da ein 64-Bit-Float nicht so viele signifikante Ziffern darstellen kann. Sie können dies mit der Auswertung überprüfen 1.9999999999999999 == 2.0. Und wenn Sie den Verdacht haben, dass die Operation equals auf Floats etwas rundet, können Sie die binäre Darstellung mit vergleichen struct.pack("d", 1.9999999999999999) == struct.pack("d", 2.0), die ebenfalls gleich ist.
Blubberdiblub

4
Und wenn das genau Ihr Punkt ist, dann sehe ich nicht, was los ist int(). Der Wert ist bereits 2.0 und es wird ihn glücklich in 2 umwandeln.
blubberdiblub

1
Wenn OPs (oder wer auch immer dies in Zukunft liest) beabsichtigen, aus irgendeinem Grund die nächste Ganzzahl (und nicht den Aufrundungswert) zu verwenden, sollten Sie dies berücksichtigen.
Lokilindo

3
@lokilindo Aber das hat nichts damit zu tun int(), es hat nur mit einer missbräuchlichen Verwendung vonfloat zu tun , wie 1.9999999999999999es zur 2.0 Kompilierungszeit aufgerundet wird (während int()es zur Ausführungszeit aufgerufen wird). Wenn Sie den richtigen Datentyp für die Variable verwenden, funktioniert alles wie erwartet: int(decimal.Decimal('1.9999999999999999999999999999999999999999999999999999999'))gibt1
Tino

6

Wenn Sie keine Mathematik importieren möchten, können Sie Folgendes verwenden:

int(round(x))

Hier ist eine Dokumentation:

>>> help(round)
Help on built-in function round in module __builtin__:

round(...)
    round(number[, ndigits]) -> floating point number

    Round a number to a given precision in decimal digits (default 0 digits).
    This always returns a floating point number.  Precision may be negative.

Danke für deine Antwort. Das nächste Mal erhalten Sie einen besseren Empfang, wenn Sie den richtigen Code schreiben (in Klammern schließen) und eine Dokumentation geben.
Geoff

2
roundwurde bereits als Antwort diskutiert und abgelehnt, als diese Frage vor einem Jahr gestellt wurde. OP will math.floor.
Adam Smith

3

Wenn Sie mit numpy arbeiten, können Sie die folgende Lösung verwenden, die auch mit negativen Zahlen funktioniert (sie funktioniert auch mit Arrays).

import numpy as np
def round_down(num):
    if num < 0:
        return -np.ceil(abs(num))
    else:
        return np.int32(num)
round_down = np.vectorize(round_down)

round_down([-1.1, -1.5, -1.6, 0, 1.1, 1.5, 1.6])
> array([-2., -2., -2.,  0.,  1.,  1.,  1.])

Ich denke, es wird auch funktionieren, wenn Sie nur das mathModul anstelle des numpyModuls verwenden.


1

Ich weiß nicht, ob Sie das gelöst haben, aber ich stolpere nur über diese Frage. Wenn Sie Dezimalstellen entfernen möchten, können Sie int (x) verwenden, um alle Dezimalstellen zu entfernen. Es ist nicht erforderlich, rund (x) zu verwenden.


1

Machen Sie einfach rund (x-0,5). Dies gibt immer den nächsten abgerundeten Integer-Wert Ihres Floats zurück. Sie können auch einfach durch Runden aufrunden (x + 0,5).


-1

Es mag sehr einfach sein, aber könnten Sie es dann nicht einfach auf minus 1 aufrunden? Beispielsweise:

number=1.5
round(number)-1
> 1

4
Dies gibt die falsche Antwort für ganze ganze Zahlen. Zum Beispiel ist 2.0 aufgerundet 2, und wenn Sie 1 subtrahieren, erhalten Sie das falsche Ergebnis 1.
Pascal Cuoq

@PascalCuoq Ich verstehe dein Problem nicht. Möchten Sie 1.0 als Ergebnis? Weil OP eindeutig abrunden wollte, dann auf den nächsten nummerieren integer.
bad_keypoints

1
@bad_keypoints Ich glaube nicht, dass das OP 2.0 zu 1 runden will.
Pascal Cuoq

@PascalCuoq Entschuldigung, ich habe gerade auf die Antwort im Kommentarthread zurückgeblickt, von der wir sind.
bad_keypoints

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.