2010-01-20 24 views
78

Qualcuno sa come Python gestisce internamente int e long?In che modo Python gestisce int e long?

  • Seleziona il tipo giusto in modo dinamico?
  • Qual è il limite per un int?
  • Sto usando Python 2.6, Is è diverso dalle versioni precedenti?

Come devo capire il codice qui sotto?

>>> print type(65535) 
<type 'int'> 
>>> print type(65536*65536) 
<type 'long'> 

Aggiornamento:

>>> print type(0x7fffffff) 
<type 'int'> 
>>> print type(0x80000000) 
<type 'long'> 
+0

Non si limitano a eseguire il mapping ai tipi stdc al volo sottotitoli in CPython? –

+0

Sì, penso che lo facciano. Sospetto anche che tutto sia allocato sull'heap, quindi quando un numero ha bisogno di maggiore precisione, semplicemente "realloc" va tutto bene. Ma non ne sono sicuro, quindi lascerò la risposta a qualcun altro. – zneak

+1

Puoi anche forzare python a usare la variabile lunga con 'var = 666L' – qba

risposta

79

int e long erano "unificata" a few versions back. Prima era possibile traboccare un int attraverso operazioni matematiche.

3.x ha ulteriormente avanzato questo eliminando int completamente e avendo solo lungo.

Python 2: sys.maxint contiene il valore massimo che può contenere un int Python.

Python 3: sys.maxsize contiene il valore massimo che può contenere un int Python.

+16

Ma Python3 chiama questo tipo 'int', anche se si comporta più come 2.x di "long". –

+3

Commento di Ted: come indicato di seguito fate attenzione che la fusione qualcosa a int che è più grande di maxint sarà ancora tradursi in una lunga >>> tipo (int (sys.maxint + 1)) StuartLC

+2

sys.maxint vi darà il più grande numero intero a 64 bit (sulla mia macchina a 64 bit) a Lungo può essere molto più grande di 64 bit, basta provare "sys.maxint << 1000000" – fccoelho

11

Questo PEP dovrebbe essere d'aiuto.

Linea di fondo è che davvero non dovrebbe avere a preoccuparsi in versioni di Python> 2.4

+8

Devi preoccuparti se devi chiamare una funzione int in c con qualcosa che non si adatta a int (cioè un lungo). Nessuna quantità di casting long-> int aiuterà. Mi è successo proprio di recente. – Macke

+1

@Macke: questo commento mi ha salvato, ho pensato che int avrebbe fatto il trucco, e mi stavo chiedendo perché stavo ancora ottenendo un'eccezione Jython. – ted

+0

@Macke Assolutamente vero. In azienda lavoro attualmente con un simulatore scritto in Python che accetta l'input dell'utente attraverso le voci di Tkinter e invia i valori castati via TCP/IP a un client (scritto in C/C++) che riproduce un sistema incorporato. Immagina cosa succede quando inserisci 100000000000000000000000 nella tua voce basata su Python ...: P – rbaleksandar

3

Sulla mia macchina:

>>> print type(1<<30) 
<type 'int'> 
>>> print type(1<<31) 
<type 'long'> 
>>> print type(0x7FFFFFFF) 
<type 'int'> 
>>> print type(0x7FFFFFFF+1) 
<type 'long'> 

Python usa interi (32 bit interi firmato, I don' so se sono C ints under the hood o no) per valori che si adattano a 32 bit, ma passa automaticamente a long (numero arbitrariamente elevato di bit - cioè bignum) per qualcosa di più grande. Immagino che questo accelera le cose per valori più piccoli evitando qualsiasi trabocco con una transizione senza interruzioni verso i bignum.

0

Li gestisce perché int e long sono definizioni di classi di pari livello. Hanno metodi appropriati per +, -, *, /, ecc., Che produrranno i risultati della classe appropriata.

Ad esempio

>>> a=1<<30 
>>> type(a) 
<type 'int'> 
>>> b=a*2 
>>> type(b) 
<type 'long'> 

In questo caso, la classe int ha un metodo __mul__ (quello che implementa *), che crea un risultato long quando richiesto.

3

Interessante. Sul mio 64-bit (i7 Ubuntu) scatola:

>>> print type(0x7FFFFFFF) 
<type 'int'> 
>>> print type(0x7FFFFFFF+1) 
<type 'int'> 

Immagino che i passaggi fino a 64 bit interi su una macchina più grande.

+2

Python usa il tipo intero più grande disponibile per la macchina. SO di solito su macchine a 32 bit int avrà una dimensione a 32 bit, mentre su macchine a 64 bit avrà una dimensione a 64 bit. Ma ci potrebbero essere architetture a 32 bit che definiscono interi a 64 bit, in questo caso python userebbe l'intero a 64 bit. – Bakuriu

0

Da python 3.x, le librerie di interi unificati sono ancora più intelligenti rispetto alle versioni precedenti.Sulla mia casella (i7 Ubuntu) ho ottenuto il seguente,

>>> type(math.factorial(30)) 
<class 'int'> 

Per i dettagli di implementazione riferimento Include/longintrepr.h, Objects/longobject.c and Modules/mathmodule.c file. L'ultimo file è un modulo dinamico (compilato in un file così). Il codice è ben commentato da seguire.

2

Python 2.7.9 promuove automaticamente i numeri. Per un caso in cui non si è sicuri di utilizzare int() o long().

>>> a = int("123") 
>>> type(a) 
<type 'int'> 
>>> a = int("111111111111111111111111111111111111111111111111111") 
>>> type(a) 
<type 'long'>