Wie kann ich die Division als Gleitkomma erzwingen? Division rundet weiter auf 0?

721

Ich habe zwei ganzzahlige Werte aund b, aber ich brauche ihr Verhältnis in Gleitkomma. Ich weiß das a < bund möchte berechnen a / b. Wenn ich also eine ganzzahlige Division verwende, erhalte ich immer 0 mit einem Rest von a.

Wie kann ich cim Folgenden erzwingen , eine Gleitkommazahl in Python zu sein?

c = a / b
Nathan Fellman
quelle
Aktualisieren Sie einfach auf Python 3.
Boris

Antworten:

807

In Python 2 erzeugt die Division von zwei Ints ein int. In Python 3 wird ein Float erzeugt. Wir können das neue Verhalten durch Importieren aus erhalten __future__.

>>> from __future__ import division
>>> a = 4
>>> b = 6
>>> c = a / b
>>> c
0.66666666666666663
Michael Fairley
quelle
13
Beachten Sie, dass from __future__ import divisionganz am Anfang der Datei sein muss
Yannis
Das Problem ist auch, wenn Sie die Ganzzahldivision an einer Stelle, aber die
Floatdivision
1
@ mercury0114: Kein Problem; Sie verwenden nur, //wenn Sie eine Bodenteilung wünschen und /wenn Sie eine "wahre" ( float) Teilung wünschen .
ShadowRanger
715

Sie können werfen, um zu schweben, indem Sie tun c = a / float(b). Wenn der Zähler oder Nenner ein Float ist, ist das Ergebnis auch.


Eine Einschränkung: Wie Kommentatoren hervorgehoben haben, funktioniert dies nicht, wenn es sich bmöglicherweise nicht um eine Ganzzahl oder eine Gleitkommazahl (oder eine Zeichenfolge, die eine darstellt) handelt. Wenn Sie möglicherweise mit anderen Typen (z. B. komplexen Zahlen) zu tun haben, müssen Sie entweder nach diesen suchen oder eine andere Methode verwenden.

Steve Trout
quelle
195

Wie kann ich die Division in Python als Gleitkomma erzwingen?

Ich habe zwei ganzzahlige Werte a und b, aber ich brauche ihr Verhältnis in Gleitkomma. Ich weiß, dass a <b und ich möchte a / b berechnen. Wenn ich also eine ganzzahlige Division verwende, erhalte ich immer 0 mit einem Rest von a.

Wie kann ich im Folgenden erzwingen, dass c in Python eine Gleitkommazahl ist?

c = a / b

Was hier wirklich gefragt wird, ist:

"Wie erzwinge ich eine echte Teilung, a / bdie einen Bruchteil zurückgibt?"

Upgrade auf Python 3

In Python 3 tun Sie dies einfach, um eine echte Teilung zu erzielen a / b.

>>> 1/2
0.5

Die Bodenteilung, das klassische Teilungsverhalten für ganze Zahlen, lautet nun a // b:

>>> 1//2
0
>>> 1//2.0
0.0

Möglicherweise stecken Sie jedoch mit Python 2 fest, oder Sie schreiben Code, der sowohl in 2 als auch in 3 funktionieren muss.

Bei Verwendung von Python 2

In Python 2 ist das nicht so einfach. Einige Möglichkeiten, mit der klassischen Python 2-Division umzugehen, sind besser und robuster als andere.

Empfehlung für Python 2

Sie können das Python 3-Teilungsverhalten in jedem Modul mit dem folgenden Import oben abrufen:

from __future__ import division

Dadurch wird die Python 3-Stilteilung auf das gesamte Modul angewendet. Es funktioniert auch in einer Python-Shell an einem bestimmten Punkt. In Python 2:

>>> from __future__ import division
>>> 1/2
0.5
>>> 1//2
0
>>> 1//2.0
0.0

Dies ist wirklich die beste Lösung, da dadurch sichergestellt wird, dass der Code in Ihrem Modul vorwärtskompatibler mit Python 3 ist.

Andere Optionen für Python 2

Wenn Sie dies nicht auf das gesamte Modul anwenden möchten, sind Sie auf einige Problemumgehungen beschränkt. Am beliebtesten ist es, einen der Operanden zu einem Float zu zwingen. Eine robuste Lösung ist a / (b * 1.0). In einer frischen Python-Shell:

>>> 1/(2 * 1.0)
0.5

Auch robust ist truedivvom operatorModul operator.truediv(a, b), aber dies ist wahrscheinlich langsamer, weil es ein Funktionsaufruf ist:

>>> from operator import truediv
>>> truediv(1, 2)
0.5

Nicht empfohlen für Python 2

Häufig gesehen ist a / float(b). Dies löst einen TypeError aus, wenn b eine komplexe Zahl ist. Da die Division mit komplexen Zahlen definiert ist, ist es für mich sinnvoll, dass die Division nicht fehlschlägt, wenn eine komplexe Zahl für den Divisor übergeben wird.

>>> 1 / float(2)
0.5
>>> 1 / float(2j)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't convert complex to float

Es macht für mich nicht viel Sinn, Ihren Code gezielt brüchiger zu machen.

Sie können Python auch mit dem -QnewFlag ausführen. Dies hat jedoch den Nachteil, dass alle Module mit dem neuen Python 3-Verhalten ausgeführt werden. Einige Ihrer Module erwarten möglicherweise eine klassische Aufteilung. Daher empfehle ich dies nur zum Testen. Aber um zu demonstrieren:

$ python -Qnew -c 'print 1/2'
0.5
$ python -Qnew -c 'print 1/2j'
-0.5j
Aaron Hall
quelle
3
"1 // 2 = 0", "1 // 2.0 = 0.0" - interessantes kleines Gotcha, selbst wenn es sich um eine ganzzahlige Division handelt, wenn einer der Operanden float ist, ist das Ergebnis eine ganze Zahl, aber auch float. Ich habe eine Ganzzahldivision verwendet, um einen Listenindex zu berechnen und aus diesem Grund einen Fehler zu erhalten.
R. Navega
134
c = a / (b * 1.0)
Binokel
quelle
66

In Python 3.x bedeutet der einzelne Schrägstrich ( /) immer eine echte (nicht abschneidende) Teilung. (Der //Operator wird zum Abschneiden der Division verwendet.) In Python 2.x (2.2 und höher) können Sie dasselbe Verhalten erzielen, indem Sie a eingeben

from __future__ import division

oben in Ihrem Modul.

newacct
quelle
30

Wenn Sie nur einen der Parameter für die Division im Gleitkommaformat festlegen, wird auch die Ausgabe im Gleitkommaformat ausgeführt.

Beispiel:

>>> 4.0/3
1.3333333333333333

oder,

>>> 4 / 3.0
1.3333333333333333

oder,

>>> 4 / float(3)
1.3333333333333333

oder,

>>> float(4) / 3
1.3333333333333333
gsbabil
quelle
4
Aber Sie könnten später versucht sein, 1.0 + 1/3oder float(c) + a/boder float(a/b)und Sie werden von der Antwort enttäuscht sein. Verwenden Sie besser Python 3+ oder importieren Sie das __future__.divisionModul (siehe akzeptierte Antwort), um immer die erwartete Antwort zu erhalten. Die vorhandenen Teilungsregeln verursachen heimtückische, schwer nachvollziehbare mathematische Fehler.
Kochfelder
@ JoeCondron Hast du es versucht python -c 'a=10; b=3.0; print a/b'?
gsbabil
Ich musste nicht, weil es in diesem Szenario offensichtlich funktioniert. Was ist jedoch, wenn aund 'b' z. B. die Ausgaben einer Ganzzahlwertfunktion sind? ZB , a = len(list1), b = len(list2).
JoeCondron
@ JoeCondron: guter Punkt. Ich habe gerade die Antwort aktualisiert, um sie aufzunehmen float(..). Ich denke, das Multiplizieren mit 1.0, wie @Pinochle unten vorgeschlagen hat, könnte ebenfalls nützlich sein.
gsbabil
21

Fügen Sie einen Punkt ( .) hinzu, um Gleitkommazahlen anzugeben

>>> 4/3.
1.3333333333333333
Alexander
quelle
2
Wie werden Sie diesen Ansatz anwenden, wenn Zähler und Nenner beide Variablen sind?
stackoverflowuser2010
Ich gehe davon aus, dass Sie sich auf das erste Beispiel beziehen. Wenn dem so ist, würde ich es nur float()für eine der Variablen verwenden.
Alexander
13

Dies wird auch funktionieren

>>> u=1./5
>>> print u
0.2
Gaurav Agarwal
quelle
4
Und wie werden Sie diesen Ansatz anwenden, wenn Zähler und Nenner beide Variablen sind?
stackoverflowuser2010
1
Weil es nicht funktioniert, wenn Variablen für die Abstraktion verwendet werden. Fast kein aussagekräftiger Code hat so fest codierte Werte.
Keir Simmons
1
Dies hat wenig Stimmen, weil diese Antwort die Frage nicht beantwortet und überhaupt keine allgemeine Antwort ist. In einer Antwort ist es auch wichtig, zuerst zu zeigen, warum dies funktioniert. Es ist sehr einfach: Wenn der Zähler oder Nenner ein Float ist, ist das Ergebnis ein Float. Normalerweise verwenden Sie Python nicht als Klartextrechner, daher möchten Sie eine Antwort für Variablen aund b.
TimZaman
Für die längste Zeit dachte ich tatsächlich, es ./sei ein gültiger Operator in Python, mit dem Sie Gleitkommadivisionen durchführen können. Aus diesem Grund ist es gut, Leerzeichen in jeder Programmiersprache mit
Bedacht zu
6

Wenn Sie standardmäßig die Division "true" (Gleitkomma) verwenden möchten, gibt es ein Befehlszeilenflag:

python -Q new foo.py

Es gibt einige Nachteile (aus dem PEP):

Es wurde argumentiert, dass eine Befehlszeilenoption zum Ändern der Standardeinstellung böse ist. In den falschen Händen kann es sicherlich gefährlich sein: Zum Beispiel wäre es unmöglich, ein Bibliothekspaket eines Drittanbieters, das -Qnew erfordert, mit einem anderen zu kombinieren, das -Qold erfordert.

Weitere Informationen zu den anderen Flags-Werten, die das Verhalten der Division ändern / warnen, finden Sie in der Python-Manpage.

Ausführliche Informationen zu Abteilungsänderungen finden Sie unter: PEP 238 - Ändern des Abteilungsoperators

stephenbez
quelle
2
from operator import truediv

c = truediv(a, b)
JoeCondron
quelle
2
Das ist jedoch nicht ideal, da es nicht funktioniert, wenn es sich aum ein int und bein float handelt. Eine bessere Lösung in die gleiche Richtung ist zu tun from operator import truedivund dann zu verwenden truediv(a, b).
Mark Dickinson
Ja, du hast recht. Ich habe beide ganzen Zahlen angenommen, da dies das einzige Mal ist, wenn sich die Divisionsoperationen unterscheiden, aber Sie wirklich eine allgemeine Lösung wollen. Ich wusste nicht, dass Sie den Operator importieren können oder dass er für Float-Teiler überhaupt nicht funktioniert. Antwort bearbeitet.
JoeCondron
1
from operator import truediv

c = truediv(a, b)

Dabei ist a die Dividende und b der Divisor. Diese Funktion ist praktisch, wenn der Quotient nach der Division zweier Ganzzahlen ein Float ist.

Chetan Yeshi
quelle