Grundsätzlich konvertiere ich einen Float in einen Int, aber ich habe nicht immer den erwarteten Wert.
Hier ist der Code, den ich ausführe:
x = 2,51
print("--------- 251.0")
y = 251.0
print(y)
print(int(y))
print("--------- 2.51 * 100")
y = x * 100
print(y)
print(int(y))
print("--------- 2.51 * 1000 / 10")
y = x * 1000 / 10
print(y)
print(int(y))
print("--------- 2.51 * 100 * 10 / 10")
y = x * 100 * 10 / 10
print(y)
print(int(y))
x = 4.02
print("--------- 402.0")
y = 402.0
print(y)
print(int(y))
print("--------- 4.02 * 100")
y = x * 100
print(y)
print(int(y))
print("--------- 4.02 * 1000 / 10")
y = x * 1000 / 10
print(y)
print(int(y))
print("--------- 4.02 * 100 * 10 / 10")
y = x * 100 * 10 / 10
print(y)
print(int(y))
Und hier ist das Ergebnis (der erste Wert ist das Ergebnis der Operation, der zweite Wert ist int () derselben Operation):
--------- 251.0
251.0
251
--------- 2.51 * 100
251.0
250
--------- 2.51 * 1000 / 10
251.0
251
--------- 2.51 * 100 * 10 / 10
251.0
250
--------- 402.0
402.0
402
--------- 4.02 * 100
402.0
401
--------- 4.02 * 1000 / 10
402.0
401
--------- 4.02 * 100 * 10 / 10
402.0
401
2,51 und 4,02 sind die einzigen Werte, die zu diesem seltsamen Verhalten im Bereich von 2,50 -> 5,00 führen. Alle zwei zweistelligen Werte in diesem Bereich werden bei gleichen Operationen problemlos in int konvertiert.
Was fehlt mir also, was zu diesen Ergebnissen führt? Ich benutze übrigens Python 2.7.2.
python
floating-point
int
B. Richard
quelle
quelle
nfloor = lambda x: round(x * 10**8) // 10**8
Antworten:
2.51 * 100 = 250.999999999997
Die
int()
Funktion schneidet einfach die Zahl am Dezimalpunkt ab und ergibt 250. Verwenden Sieint(round(2.51*100))
251 als ganze Zahl zu erhalten. Im Allgemeinen können Gleitkommazahlen nicht genau dargestellt werden. Man sollte daher auf Rundungsfehler achten. Wie bereits erwähnt, ist dies kein Python-spezifisches Problem. Es ist ein wiederkehrendes Problem in allen Computersprachen.
quelle
Was jeder Informatiker über Gleitkomma-Arithmetik wissen sollte
Gleitkommazahlen können nicht alle Zahlen darstellen. Insbesondere kann 2.51 nicht durch eine Gleitkommazahl dargestellt werden und wird durch eine Zahl sehr nahe daran dargestellt:
>>> print "%.16f" % 2.51 2.5099999999999998 >>> 2.51*100 250.99999999999997 >>> 4.02*100 401.99999999999994
Wenn Sie int verwenden, wodurch die Zahlen abgeschnitten werden, erhalten Sie:
250 401
Schauen Sie sich den Dezimaltyp an .
quelle
float
der eine endliche Anzahl von Bits aufweist.Sprachen, die binäre Gleitkomma-Darstellungen verwenden (Python ist eine), können nicht alle Bruchwerte genau darstellen. Wenn das Ergebnis Ihrer Berechnung 250.99999999999 ist (und es könnte sein), führt die Verwendung des ganzzahligen Teils zu 250.
Ein kanonischer Artikel zu diesem Thema ist das, was jeder Informatiker über Gleitkomma-Arithmetik wissen sollte .
quelle
>>> x = 2.51 >>> x*100 250.99999999999997
Die Gleitkommazahlen sind ungenau. In diesem Fall ist es 250.9999999999999999, was sehr nahe an 251 liegt, aber int () schneidet den Dezimalteil ab, in diesem Fall 250.
Sie sollten sich das Dezimalmodul ansehen oder wenn Sie in der mpmath-Bibliothek http://code.google.com/p/mpmath/ :) viel rechnen müssen.
quelle
int()
rundet nicht auf die Ganzzahl unten, sondern schneidet den Dezimalteil ab. Beispiel :int(-0.9) == 0
.int
konvertiert durch Abschneiden, wie von anderen erwähnt wurde. Dies kann dazu führen, dass die Antwort anders als erwartet ist. Eine Möglichkeit, dies zu umgehen, besteht darin, zu überprüfen, ob das Ergebnis nahe genug an einer Ganzzahl liegt, und es entsprechend anzupassen, andernfalls die übliche Konvertierung. Dies setzt voraus, dass Sie nicht zu viele Rundungs- und Berechnungsfehler erhalten, was ein separates Problem ist. Zum Beispiel:def toint(f): trunc = int(f) diff = f - trunc # trunc is one too low if abs(f - trunc - 1) < 0.00001: return trunc + 1 # trunc is one too high if abs(f - trunc + 1) < 0.00001: return trunc - 1 # trunc is the right value return trunc
Diese Funktion passt Off-by-One-Fehler für nahe ganze Zahlen an. Die
mpmath
Bibliothek macht etwas Ähnliches für Gleitkommazahlen, die nahe an ganzen Zahlen liegen.quelle