In che modo Python gestisce int e long?


118

Qualcuno sa come Python gestisce internamente i tipi int e long?

  • Sceglie il tipo giusto dinamicamente?
  • Qual è il limite per un int?
  • Sto usando Python 2.6, è diverso con le versioni precedenti?

Come devo capire il codice qui sotto?

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

Aggiornare:

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

Non si limitano a mappare i tipi stdc al volo in CPython?
Aiden Bell

Sì, penso di sì. Ho anche il sospetto che tutto sia allocato nell'heap, quindi quando un numero ha bisogno di maggiore precisione, reallocva tutto bene. Ma non ne sono del tutto sicuro, quindi lascerò la risposta a qualcun altro.
Zneak

2
Puoi anche forzare python a usare la variabile long convar = 666L
qba

8
@Ignacio: SBAGLIATO Un CPython intè un C long(il default è firmato) ... vedi <CPython 2.X source>/Include/intobject.h: typedef struct {PyObject_HEAD long ob_ival; } PyIntObject; In ogni caso Python 2.x intammette numeri negativi; una C unsignedsemplicemente non ce la farebbe.
John Machin

PEP 237 discute di come sotto il cofano Python è pensato per rendere tutto questo apparentemente uguale.
Carel

Risposte:


124

inted longerano "unificate" alcune versioni precedenti . Prima di allora era possibile traboccare un int attraverso operazioni matematiche.

3.x lo ha ulteriormente migliorato eliminando del tutto long e avendo solo int.

  • Python 2 : sys.maxintcontiene il valore massimo che un int Python può contenere.
    • Su un Python 2.7 a 64 bit, la dimensione è di 24 byte. Verificare con sys.getsizeof().
  • Python 3 : sys.maxsizecontiene la dimensione massima in byte che può essere un int Python.
    • Questo sarà gigabyte a 32 bit ed exabyte a 64 bit.
    • Un int così grande avrebbe un valore simile a 8 alla potenza di sys.maxsize.

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

3
Commento di Ted: Come accennato di seguito, fai attenzione che lanciare qualcosa a int che è più grande di maxint risulterà comunque in un tipo lungo >>> (int (sys.maxint + 1)) <tipo 'lungo'>
StuartLC

2
sys.maxint ti darà il più grande numero intero a 64 bit (sulla mia macchina a 64 bit) un Long può essere molto più grande di 64 bit, prova semplicemente "sys.maxint << 1000000"
fccoelho

4
In python3 è sys.maxsize
pylover

3
sys.maxsize non ha nulla a che fare con gli interi. Il sys.maxint di Python 3 è stato rimosso perché non esiste una dimensione massima per un numero intero (quello di Python 3 intè uguale a quello di Python 2 long).
asmeurer

19

Questo PEP dovrebbe aiutare.

La linea di fondo è che non dovresti davvero preoccupartene nelle versioni di Python> 2.4


15
Devi preoccupartene 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 di recente.
Macke,

1
@Macke: Questo commento mi ha salvato, pensavo che int avrebbe fatto il trucco e mi chiedevo perché stavo ancora ricevendo un'eccezione Jython.
ted

@Macke Assolutamente vero. Nella società in cui lavoro attualmente abbiamo un simulatore scritto in Python che prende l'input dell'utente attraverso le voci di Tkinter e invia i valori trasmessi tramite TCP / IP a un client (scritto in C / C ++) che imita un sistema embedded. Immagina cosa succede quando inserisci 100000000000000000000000 nella tua voce basata su Python ...: P
rbaleksandar

@Mackie, beh, se ti sei preso la briga di leggere il PEP, dice esplicitamente: L'API C rimane invariata; Il codice C dovrà comunque essere consapevole della differenza tra int brevi e lunghi. (L'API C di Python 3.0 sarà probabilmente completamente incompatibile.) Le API PyArg_Parse * () accettano già long int, purché siano all'interno dell'intervallo rappresentabile da C int o longs, in modo che le funzioni che accettano C int o long argomento non vincano " Non devo preoccuparmi di avere a che fare con i lunghi di Python.
cowbert

4

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 int (interi con segno a 32 bit, non so se sono int di C sotto il cofano o meno) per i valori che si adattano a 32 bit, ma passa automaticamente a long (numero arbitrariamente grande di bit - cioè bignum) per qualsiasi cosa più grandi. Immagino che questo acceleri le cose per valori più piccoli evitando eventuali overflow con una transizione senza interruzioni ai bignum.


4

Interessante. Sulla mia scatola a 64 bit (i7 Ubuntu):

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

Immagino che passi fino a 64 bit su una macchina più grande.


2
Python utilizza il tipo intero più grande disponibile per la macchina. Quindi di solito su macchine a 32 bit int avrà una dimensione di 32 bit, mentre su macchine a 64 bit avrà una dimensione di 64 bit. Ma potrebbero esserci architetture a 32 bit che definiscono interi a 64 bit, in quel caso Python userebbe l'intero a 64 bit.
Bakuriu

4

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'>

4

Python 2 imposterà automaticamente il tipo in base alla dimensione del valore. Di seguito è possibile trovare una guida dei valori massimi.

Il valore massimo del valore predefinito Int in Python 2 è 65535, qualsiasi valore superiore sarà lungo

Per esempio:

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

In Python 3 il tipo di dati lungo è stato rimosso e tutti i valori interi sono gestiti dalla classe Int. La dimensione predefinita di Int dipenderà dall'architettura della CPU.

Per esempio:

  • Nei sistemi a 32 bit, il tipo di dati predefinito per gli interi sarà 'Int32'
  • Nei sistemi a 64 bit il tipo di dati predefinito per i numeri interi sarà 'Int64'

Di seguito sono riportati i valori min / max di ogni tipo:

  • Int8: [-128,127]
  • Int16: [-32768,32767]
  • Int32: [-2147483648,2147483647]
  • Int64: [-9223372036854775808,9223372036854775807]
  • Int128: [-170141183460469231731687303715884105728,170141183460469231731687303715884105727]
  • UInt8: [0,255]
  • UInt16: [0,65535]
  • UInt32: [0,4294967295]
  • UInt64: [0,18446744073709551615]
  • UInt128: [0,340282366920938463463374607431768211455]

Se la dimensione del tuo Int supera i limiti sopra menzionati, python cambierà automaticamente il suo tipo e allocherà più memoria per gestire questo aumento dei valori min / max. Dove in Python 2, si converteva in "lungo", ora si converte solo nella dimensione successiva di Int.

Esempio: se utilizzi un sistema operativo a 32 bit, il valore massimo di un Int sarà 2147483647 per impostazione predefinita. Se viene assegnato un valore di 2147483648 o superiore, il tipo verrà modificato in Int64.

Esistono diversi modi per controllare la dimensione di int e la sua allocazione di memoria. Nota: in Python 3, l'utilizzo del metodo incorporato type () restituirà sempre, <class 'int'>indipendentemente dalla dimensione Int che stai utilizzando.


1

Da python 3.x, le librerie di interi unificati sono ancora più intelligenti delle versioni precedenti. Sulla mia scatola (i7 Ubuntu) ho ottenuto quanto segue,

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

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


1

Solo per continuare con tutte le risposte che sono state fornite qui, in particolare @James Lanes

la dimensione del tipo intero può essere espressa da questa formula:

range totale = (sistema a 2 ^ bit)

limite inferiore = - (sistema a 2 ^ bit) * 0,5 limite superiore = ((sistema a 2 ^ bit) * 0,5) - 1


0

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

Per esempio

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

In questo caso, la classe intha un __mul__metodo (quello che implementa *) che crea un longrisultato quando richiesto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.