¿Cómo gestiona Python int y long?


118

¿Alguien sabe cómo Python gestiona internamente los tipos int y long?

  • ¿Elige el tipo correcto de forma dinámica?
  • ¿Cuál es el límite para un int?
  • Estoy usando Python 2.6, ¿es diferente con las versiones anteriores?

¿Cómo debo entender el siguiente código?

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

Actualizar:

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

¿No se asignan simplemente a tipos de stdc sobre la marcha debajo de CPython?
Aiden Bell

Sí, creo que sí. También sospecho que todo está asignado en el montón, por lo que cuando un número necesita más precisión, realloclo hacen bien. Pero no estoy muy seguro, así que dejaré la respuesta a otra persona.
Zneak

2
También puede forzar a Python a usar una variable larga convar = 666L
qba

8
@Ignacio: INCORRECTO Un CPython intes un C long(por defecto está firmado) ... ver <CPython 2.X source>/Include/intobject.h: typedef struct {PyObject_HEAD long ob_ival; } PyIntObject; En cualquier caso, Python 2.x intpermite números negativos; una C unsignedsimplemente no se las arreglaría.
John Machin

PEP 237 analiza cómo, bajo el capó, Python está destinado a hacer que todo esto parezca lo mismo.
Carel

Respuestas:


124

inty longfueron "unificadas" algunas versiones atrás . Antes de eso, era posible desbordar un int a través de operaciones matemáticas.

3.x ha avanzado aún más en esto al eliminar long por completo y solo tener int.

  • Python 2 : sys.maxintcontiene el valor máximo que puede contener un int de Python.
    • En un Python 2.7 de 64 bits, el tamaño es de 24 bytes. Consulte con sys.getsizeof().
  • Python 3 : sys.maxsizecontiene el tamaño máximo en bytes que puede tener un int de Python.
    • Esto será gigabytes en 32 bits y exabytes en 64 bits.
    • Un int tan grande tendría un valor similar a 8 elevado a la potencia de sys.maxsize.

30
Pero Python3 llama a este tipo 'int', aunque se comporta más como el 'long' de 2.x.

3
Comentario de Ted: Como se menciona a continuación, tenga en cuenta que enviar algo a int que sea más grande que maxint aún resultará en un tipo largo >>> (int (sys.maxint + 1)) <tipo 'largo'>
StuartLC

2
sys.maxint le dará el entero de 64 bits más grande (en mi máquina de 64 bits). Long puede ser mucho más grande que 64 bits, solo intente "sys.maxint << 1000000"
fccoelho

4
En python3 es sys.maxsize
pylover

3
sys.maxsize no tiene nada que ver con números enteros. Se eliminó sys.maxint de Python 3 porque no hay un tamaño máximo para un número entero (Python 3 intes lo mismo que Python 2 long).
asmeurer

19

Este PEP debería ayudar.

La conclusión es que realmente no debería tener que preocuparse por eso en las versiones de Python> 2.4


15
Tienes que preocuparte por eso si tienes que llamar a una función int en c con algo que no encaja en int (es decir, a long). Ninguna cantidad de casting long-> int ayudará. Me pasó hace poco.
Macke

1
@Macke: Este comentario me salvó, asumí que int haría el truco, y me preguntaba por qué todavía recibía una excepción de Jython.
ted

@Macke Absolutamente cierto. En la empresa en la que trabajo actualmente tenemos un Simulador escrito en Python que toma la entrada del usuario a través de las entradas de Tkinter y envía los valores emitidos a través de TCP / IP a un cliente (escrito en C / C ++) que imita un sistema integrado. Imagínese lo que sucede cuando inserta 100000000000000000000000 en su entrada basada en Python ...: P
rbaleksandar

@Mackie bueno, si realmente se molestó en leer el PEP, explícitamente dice: La API C permanece sin cambios; El código C aún necesitará ser consciente de la diferencia entre entradas cortas y largas. (La API de Python 3.0 C probablemente será completamente incompatible). Las API de PyArg_Parse * () ya aceptan ints largos, siempre que estén dentro del rango representable por ints o longs de C, por lo que las funciones que toman C int o argumentos largos ganan ' No tengo que preocuparme por lidiar con Python largos.
Cowbert

4

En mi maquina:

>>> 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 ints (enteros de 32 bits con signo, no sé si son C ints bajo el capó o no) para valores que encajan en 32 bits, pero cambia automáticamente a longs (cantidad arbitrariamente grande de bits, es decir, bignums) para cualquier cosa más grande. Supongo que esto acelera las cosas para valores más pequeños al tiempo que evita cualquier desbordamiento con una transición perfecta a bignums.


4

Interesante. En mi caja de 64 bits (i7 Ubuntu):

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

Supongo que aumenta a entradas de 64 bits en una máquina más grande.


2
Python usa el tipo de entero más grande disponible para la máquina. Por lo general, en máquinas de 32 bits, int tendrá un tamaño de 32 bits, mientras que en máquinas de 64 bits tendrá un tamaño de 64 bits. Pero podría haber arquitecturas de 32 bits que definan enteros de 64 bits, en ese caso Python usaría el entero de 64 bits.
Bakuriu

4

Python 2.7.9 promueve automáticamente los números. Para un caso en el que uno no está seguro de usar int () o long ().

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

4

Python 2 establecerá automáticamente el tipo según el tamaño del valor. A continuación se puede encontrar una guía de valores máximos.

El valor máximo del Int predeterminado en Python 2 es 65535, todo lo que esté por encima será un largo

Por ejemplo:

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

En Python 3, el tipo de datos largo se ha eliminado y la clase Int maneja todos los valores enteros. El tamaño predeterminado de Int dependerá de la arquitectura de su CPU.

Por ejemplo:

  • Sistemas de 32 bits, el tipo de datos predeterminado para enteros será 'Int32'
  • Sistemas de 64 bits, el tipo de datos predeterminado para enteros será 'Int64'

Los valores mínimo / máximo de cada tipo se pueden encontrar a continuación:

  • 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]

Si el tamaño de su Int excede los límites mencionados anteriormente, Python cambiará automáticamente su tipo y asignará más memoria para manejar este aumento en los valores mínimo / máximo. Donde en Python 2, se convertiría en 'largo', ahora simplemente se convierte en el siguiente tamaño de Int.

Ejemplo: si está utilizando un sistema operativo de 32 bits, su valor máximo de un Int será 2147483647 por defecto. Si se asigna un valor de 2147483648 o más, el tipo se cambiará a Int64.

Hay diferentes formas de verificar el tamaño del int y su asignación de memoria. Nota: En Python 3, el uso del método integrado type () siempre devolverá <class 'int'>sin importar el tamaño de Int que esté usando.


1

Desde python 3.x, las bibliotecas de enteros unificadas son incluso más inteligentes que las versiones anteriores. En mi caja (i7 Ubuntu) obtuve lo siguiente,

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

Para obtener detalles sobre la implementación, consulte los Include/longintrepr.h, Objects/longobject.c and Modules/mathmodule.carchivos. El último archivo es un módulo dinámico (compilado en un archivo so). El código está bien comentado para seguir.


1

Solo para continuar con todas las respuestas que se dieron aquí, especialmente @James Lanes

el tamaño del tipo entero se puede expresar mediante esta fórmula:

rango total = (sistema de 2 ^ bits)

límite inferior = - (sistema de 2 ^ bits) * 0.5 límite superior = ((sistema de 2 ^ bits) * 0.5) - 1


0

Los gestiona porque intylong son definiciones de clases hermanas. Tienen métodos apropiados para +, -, *, /, etc., que producirán resultados de la clase apropiada.

Por ejemplo

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

En este caso, la clase inttiene un __mul__método (el que implementa *) que crea un longresultado cuando se requiere.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.