Falsche Mathematik mit Python?

78

Ich fange gerade mit Python an, das ist wahrscheinlich mein Fehler, aber ...

Ich probiere Python aus. Ich benutze es gerne als Taschenrechner und arbeite langsam an einigen Tutorials.

Ich bin heute auf etwas Seltsames gestoßen. Ich wollte 2013 * 2013 herausfinden, aber ich habe das Falsche geschrieben und 2013 * 013 geschrieben und Folgendes erhalten:

>>> 2013*013
22143

Ich habe mit meinem Taschenrechner nachgesehen und 22143 ist die falsche Antwort! 2013 * 13 soll 26169 sein.

Warum gibt mir Python eine falsche Antwort? Mein alter Casio-Rechner macht das nicht ...

James Elegan
quelle
6
+1 für das tatsächliche Bemerken. Ich wusste, dass es eine Oktalzahl war, aber wenn ich es nicht gewusst hätte, würde ich jetzt denken, dass 2013 * 13 22143 war. Wie haben Sie herausgefunden, dass es die falsche Antwort war?
11684
11
Ich habe vor einiger Zeit in der High School mentale Mathematik gemacht und dachte, 22143 sei etwas kleiner als es sein sollte. Also habe ich mit meinem vertrauenswürdigen Taschenrechner nachgesehen.
James Elegan
2
+1 für das Vertrauen in deinen guten alten Noggin.
Sean Allred
13
@ 11684 Wenn die letzte Ziffer in beiden Zahlen 3 ist, muss die letzte Ziffer des Produkts 9 sein. Grundschule Mathematik ...
Aleksandar

Antworten:

137

Aufgrund der Oktalarithmetik ist 013 tatsächlich die ganze Zahl 11.

>>> 013
11

Mit einer führenden Null 013wird als Basis-8-Zahl und 1 * 8 1 + 3 * 8 0 = 11 interpretiert .

Hinweis: Dieses Verhalten wurde in Python 3 geändert . Hier ist ein besonders passendes Zitat aus PEP 3127

Die standardmäßige oktale Darstellung von Ganzzahlen ist für Personen, die mit C-ähnlichen Sprachen nicht vertraut sind, stillschweigend verwirrend. Es ist extrem einfach, versehentlich ein ganzzahliges Objekt mit dem falschen Wert zu erstellen, da '013' für die Python-Sprache selbst 'Dezimal 11' und nicht 'Dezimal 13' bedeutet, was nicht die Bedeutung ist, die die meisten Menschen diesem Literal zuweisen würden .

wim
quelle
14
@ JamesElegan: Vielleicht ist das ein Grund, warum Python 3 die 0123Syntax illegal macht und immer erfordert 0o123.
Tim Pietzcker
3
Ja, das 0Präfix gefolgt von 0-8 ist oktal. 0xPräfix gefolgt von 0-9a-f ist hex.
Frambot
97
Warum verwechseln Programmierer immer Halloween und Weihnachten? Weil DEC25 == OCT31! Nyuk nyuk nyuk.
Frambot
16
@JoeFrambach, 0Präfix , gefolgt von 0- 7 ist Oktal :)
Mark Tolonen
5
Der wohlwollende Diktator hat beim ersten Mal nicht richtig von Lisp kopiert. Diese Dinge müssen laut und deutlich sein: #xFF, # o777, # b1011.
Kaz
36

013ist ein oktales Ganzzahlliteral (entspricht dem Dezimal-Ganzzahlliteral 11) aufgrund der führenden 0.

>>> 2013*013
22143
>>> 2013*11
22143
>>> 2013*13
26169

Es ist sehr üblich (sicherlich in den meisten Sprachen, mit denen ich vertraut bin), dass oktale Ganzzahlliterale mit 0und hexadezimale Ganzzahlliterale beginnen 0x. Aufgrund der genauen Verwirrung, die Sie erfahren haben, löst Python 3 einen SyntaxError aus:

>>> 2013*013
  File "<stdin>", line 1
    2013*013
           ^
SyntaxError: invalid token

und erfordert entweder 0ooder 0Ostattdessen:

>>> 2013*0o13
22143
>>> 2013*0O13
22143 
Darshan Rivka Whittle
quelle
Danke für die Antwort! Ich denke, diese oktale Sache ist ein bisschen verwirrend, aber zumindest weiß ich jetzt davon :)
James Elegan
3
Gern geschehen. Wie in meiner und der Antwort von @ wim erwähnt, unternimmt die Python-Community alles, um die Verwirrung von Neulingen in Bezug auf oktale Literale mit Python 3 zu minimieren. Trotzdem ist es eine sehr gute Sache, sich dessen bewusst zu sein - Sie können sicher sein, dass Sie darauf stoßen werden Wieder Oktal-Literale mit 0-Präfix, ob in Python 2.X oder einer anderen Sprache.
Darshan Rivka Whittle
2
Der PEP 3127 ist in dieser Hinsicht eine etwas amüsante Lektüre ... zB "Ein neuer Python-Benutzer ist möglicherweise (derzeit) verwirrt über die verspätete Entdeckung, dass seine Nummern nicht richtig funktionieren. Wir können dies beheben, indem wir ihm sofort erklären, dass Python mag keine führenden Nullen (hoffentlich mit einer vernünftigen Nachricht!), oder wir können diese Unterrichtserfahrung an den JavaScript-Interpreter im Internet Explorer-Browser delegieren und ihn versuchen lassen, sein Problem dort zu debuggen. "
wim
5

Dies erweitert meistens nur die Antwort von @ Wim ein wenig, aber Python gibt die Basis von Ganzzahlliteralen mit bestimmten Präfixen an. Ohne Präfix werden Ganzzahlen als in Basis 10 interpretiert. Bei einer "0x" wird die Ganzzahl als hexadezimales int interpretiert. Die vollständige Grammatikspezifikation finden Sie hier, obwohl es etwas schwierig zu verstehen ist, wenn Sie mit formalen Grammatiken nicht vertraut sind: http://docs.python.org/2/reference/lexical_analysis.html#integers

Die Tabelle besagt im Wesentlichen, dass Sie, wenn Sie einen langen Wert wünschen (dh einen Wert, der die Kapazität eines normalen int überschreitet), die Zahl gefolgt vom Buchstaben "L" oder "l" schreiben; Wenn Sie möchten, dass Ihre Zahl dezimal interpretiert wird, schreiben Sie die Zahl normal (ohne führende 0). Wenn Sie möchten, dass es oktal interpretiert wird, stellen Sie "0", "0o" oder "0O" voran. Wenn Sie es in hexadezimaler Form möchten, stellen Sie ihm "0x" voran. und wenn Sie es binär wollen, stellen Sie ihm "0b" oder "0B" voran.

Kyle Strand
quelle
Python scheint dieses L automatisch hinzuzufügen, wenn ich wirklich große Zahlen eingebe (wie 999999999999999999999999999, aber nicht wie 3333333333). Gibt es eine Zeit, in der ich es selbst hinzufügen müsste?
James Elegan
@ JamesElegan nur, wenn Sie eine wahnsinnig alte Version von Python verwenden. Und in Python 3 ist das L vollständig verschwunden, ebenso wie alle anderen Unterscheidungen zwischen int- und long-Typen.
lvc
Python 2.7 ist nicht wahnsinnig alt, nehme ich an? Also muss ich nie das L hinzufügen (ich höre immer wieder gute Dinge über Python 3, vielleicht sollte ich das einfach installieren und verwenden?)
James Elegan
@JamesElegan Ich kann keine genauen Informationen darüber finden, für welche frühere Version das Suffix für Literale erforderlich war, die größer waren als in ein int(und ich könnte mich tatsächlich irren, wenn es eines gibt) - mein eigenes Gedächtnis reicht so weit zurück, dass es fair ist sicher, dass 2.4 es nicht brauchte. Aber ja, Python 3 lohnt sich im Allgemeinen, wenn Sie nicht auf Bibliotheken angewiesen sind, die noch nicht portiert wurden.
lvc
Python 2.7 ist die neueste Version von Python 2; Tatsächlich wurde 2.7.4 erst an diesem Wochenende veröffentlicht. Python 3 unterscheidet sich wesentlich von Python 2, aber letztendlich wird der größte Teil des Python-Codes in nicht allzu ferner Zukunft als Python 3-Code geschrieben, oder zumindest scheint dies das Ziel zu sein. Also, wenn Sie gerade erst anfangen und wählen können, welche Sie lernen möchten, würde ich entweder 3 oder beide 2 und 3 empfehlen.
Kyle Strand