2013-04-09 1 views
77

Appena iniziato con Python, quindi questo è probabilmente il mio errore, ma ...Matematica sbagliata con Python?

Sto provando Python. Mi piace usarlo come calcolatrice e sto lentamente lavorando attraverso alcuni tutorial.

Mi sono imbattuto in qualcosa di strano oggi. Volevo scoprire 2013 * 2013, ma ho scritto la cosa sbagliata e ha scritto 2013 * 013, e ottenuto questo:

>>> 2013*013 
22143 

Ho controllato con la mia calcolatrice, e 22143 è la risposta sbagliata! 2013 * 13 dovrebbe essere 26169.

Perché Python mi sta dando una risposta sbagliata? Mio vecchio calcolatore Casio non farlo ...

+2

correlati: http://stackoverflow.com/q/13013638/748858 – mgilson

+6

+1 per davvero notare. Sapevo che era un numero ottale, ma se non lo avessi saputo, ora penserei che 2013 * 13 fosse 22143. Come hai scoperto che era la risposta sbagliata? – 11684

+11

Ho fatto matematica mentale per un po 'al liceo, e ho pensato che il 22143 fosse un po' più piccolo di quanto dovrebbe essere. Quindi ho controllato con il mio fidato calcolatore. –

risposta

137

Poiché dell'aritmetica ottale, 013 è in realtà il numero intero 11.

>>> 013 
11 

Con uno zero, 013 viene interpretato come numero in base 8 e 1 * 8 + 3 * 8 = 11.

Nota: questo comportamento era changed in python 3. Ecco una citazione particolarmente appropriato dal PEP 3127

The default octal representation of integers is silently confusing to people unfamiliar with C-like languages. It is extremely easy to inadvertently create an integer object with the wrong value, because '013' means 'decimal 11', not 'decimal 13', to the Python language itself, which is not the meaning that most humans would assign to this literal.

+1

Eh? Chi userebbe Octal? –

+7

Chiunque abbia a che fare con i permessi del filesystem userà l'ottale .. – wim

+14

@JamesElegan: Forse questa è una delle ragioni per cui Python 3 rende la sintassi '0123' illegale e richiede sempre' 0o123'. –

36

013 è un intero ottale letterale (equivalente al numero intero decimale letterale 11), a causa del leader 0.

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

E 'molto comune (certamente nella maggior parte delle lingue che ho familiarità con) i letterali interi ottali iniziano con 0 e i valori interi esadecimali iniziano con 0x. A causa della confusione esatto avete sperimentato, Python 3 solleva uno SyntaxError:

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

e richiede o 0o o 0O invece:

>>> 2013*0o13 
22143 
>>> 2013*0O13 
22143 
+0

Grazie per la risposta! Penso che questa cosa ottale sia un po 'confusa, ma almeno ora lo so :) –

+3

Sei il benvenuto. Come notato nella risposta di mia e di @ wim, la comunità Python sta facendo il possibile per ridurre al minimo la confusione dei newbie attorno ai letterali ottali con Python 3. Tuttavia, è una cosa molto buona da sapere - puoi essere certo che ti imbatterai in Nuovamente i letterali ottali con prefisso 0, sia in Python 2.X sia in un altro linguaggio. –

+2

il PEP 3127 è una lettura leggermente divertente a questo riguardo ... ad es. "un nuovo utente Python può (al momento) essere mistificato alla scoperta ritardata che i suoi numeri non funzionino correttamente, possiamo aggiustarlo spiegandogli immediatamente che a Python non piacciono gli zeri iniziali (si spera con un messaggio ragionevole!), oppure possiamo delegare questa esperienza di insegnamento all'interprete JavaScript nel browser Internet Explorer, e fargli provare a eseguire il debug del suo problema lì. " – wim

5

Questo è per lo più solo espandendo su @ risposta di Wim un po ', ma Python indica la base di valori letterali interi utilizzando determinati prefissi. Senza un prefisso, gli interi vengono interpretati come in base 10. Con un "0x", il numero intero verrà interpretato come int esadecimale. Le specifiche grammaticali complete sono qui, anche se è un po 'complicato da capire se non si ha familiarità con le grammatiche formali: http://docs.python.org/2/reference/lexical_analysis.html#integers

La tabella dice essenzialmente che se si desidera un valore lungo (cioè superiore alla capacità di un normale int), scrivi il numero seguito dalla lettera "L" o "l"; se vuoi che il tuo numero sia interpretato in decimale, scrivi normalmente il numero (senza zero iniziale); se vuoi interpretarlo in ottale, prefisso con "0", "0o" o "0O"; se lo vuoi in esadecimale, prefisso con "0x"; e se lo vuoi in binario, prefisso con "0b" o "0B".

+0

Python sembra aggiungere automaticamente L, quando inserisco numeri veramente grandi (come 9999999999999999999999999, ma non come 3333333333). C'è un momento in cui dovrei aggiungerlo da solo? –

+0

@JamesElegan solo se stai usando una vecchia versione di Python.E in Python 3, la L è sparita completamente, come lo sono tutte le altre distinzioni tra int e long. – lvc

+0

Python 2.7 non è follemente vecchio, lo prendo? Quindi non ho mai bisogno di aggiungere la L. (continuo ad ascoltare cose buone su Python 3, forse dovrei semplicemente installarla e usarla?) –