2010-01-07 15 views
7

Die // "Integer-Division" Betreiber von Python überrascht mich, heute:Integer Division im Vergleich zu floored Quotient: Warum dieses überraschende Ergebnis?

>>> math.floor(11/1.1) 
10.0 
>>> 11//1.1 
9.0 

Die documentation liest "(platt) Quotient aus x und y". Also, warum ist math.floor (11/1.1) gleich 10, aber 11 // 1.1 gleich 9?

+5

http://mail.python.org/pipermail/python-dev/2007-January/070707.html – miku

+0

Die kanonische Frage für Python 2 vs 3 Division Unterschied ist [Wie kann ich zwingen, Division zu sein, Gleitpunkt in Python? Division rollt weiter auf 0] (https://stackoverflow.com/questions/1267869/how-can-i-force-division-to-be-floating-point-in-python-division-keeps-rounding) – smci

Antwort

5

Weil 1.1 nicht exakt binär dargestellt werden kann; die Approximation ist etwas kleiner als 1.1 - daher ist das Divisionsergebnis etwas zu klein.

Versuchen Sie Folgendes:

Unter Python 2, Typ an der Konsole:

>>> 1.1 
1.1000000000000001 

In Python 3.1, die Konsole 1.1 angezeigt wird, aber intern, es ist immer noch die gleiche Zahl.

Aber:

>>> 11/1.1 
10.0 

Wie gnibbler weist darauf hin, das ist das Ergebnis der „inneren Abrundung“ im Rahmen der verfügbaren Genauigkeitsgrenzen von Schwimmern. Und wie MYYN in seinem Kommentar darauf hinweist, verwendet // einen anderen Algorithmus, um das Ergebnis der Stockwerkteilung als math.floor() zu berechnen, um a == (a//b)*b + a%b so gut wie möglich zu erhalten.

Verwenden Sie den Typ Decimal, wenn Sie diese Genauigkeit benötigen.

+0

Aber nach Python '11.0/1.1 == 10.0' ist wahr – sth

+1

Wie wir wissen, 1.1 ist als 1.1000000000000001 gespeichert, so das Ergebnis 11.0/1.1 in Python ist 9.999999999999999090909090909 aber der nächste float zu dieser Zahl ist infact 10.0, so dass es passiert, dass das Ergebnis ist genau 10.0 –

+0

@Tim dachte ich, und ich glaube, das ist der Schlüssel zum Unterschied zwischen math.floor (11/1.1) und 11 // 1.1. Wie jedoch gnibbler gezeigt hat, zeigt die Tatsache, dass 1.1 durch eine etwas größere Zahl repräsentiert wird, nur an, dass math.floor (11/1.1) wirklich 9.0 sein sollte, was die ursprüngliche Frage offen lässt. – EOL