166

Does anybody know how Python manage internally int and long types?

  • Does it choose the right type dynamically?
  • What is the limit for an int?
  • I am using Python 2.6, Is is different with previous versions?

How should I understand the code below?

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

Update:

>>> print type(0x7fffffff)
<type 'int'>
>>> print type(0x80000000)
<type 'long'>
ted
  • 4,791
  • 5
  • 38
  • 84
luc
  • 41,928
  • 25
  • 127
  • 172
  • Don't they just map to stdc types on the fly underneat in CPython? – Aiden Bell Jan 20 '10 at 20:55
  • Yeah, I think they do. I also suspect that everything is allocated on the heap, so when a number needs more precision they just `realloc` it all right. But I'm not quite sure, so I'll leave the answer to someone else. – zneak Jan 20 '10 at 21:00
  • 2
    You can also force python to use long variable with `var = 666L` – qba Jan 20 '10 at 21:04
  • 10
    @Ignacio: **WRONG** A CPython `int` is a C `long` (default is signed) ... see `/Include/intobject.h`: typedef struct { PyObject_HEAD long ob_ival; } PyIntObject; In any case Python 2.x `int` allows negative numbers; a C `unsigned` just wouldn't cope. – John Machin Jan 20 '10 at 22:47
  • PEP 237 discusses how under the hood Python is meant to make this all seemlessly the same. – Carel Apr 21 '17 at 18:58

9 Answers9

165

int and long were "unified" a few versions back. Before that it was possible to overflow an int through math ops.

3.x has further advanced this by eliminating long altogether and only having int.

  • Python 2: sys.maxint contains the maximum value a Python int can hold.
    • On a 64-bit Python 2.7, the size is 24 bytes. Check with sys.getsizeof().
  • Python 3: sys.maxsize contains the maximum size in bytes a Python int can be.
    • This will be gigabytes in 32 bits, and exabytes in 64 bits.
    • Such a large int would have a value similar to 8 to the power of sys.maxsize.
Cristian Ciupitu
  • 20,270
  • 7
  • 50
  • 76
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 37
    But Python3 calls this type 'int', even though it behaves more like 2.x's 'long'. –  Jan 20 '10 at 21:03
  • 3
    Comment by Ted : As mentioned below beware that casting something to int that is larger than maxint will still result in a long >>>type(int(sys.maxint+1)) – StuartLC Oct 25 '12 at 09:51
  • 2
    sys.maxint will give you the largest 64bit integer (on my 64bit machine) a Long can be much larger that 64bits, just try "sys.maxint << 1000000" – fccoelho Mar 28 '13 at 14:57
  • 5
    In python3 it is sys.maxsize – pylover Feb 12 '14 at 19:11
  • 4
    sys.maxsize has nothing to do with integers. Python 3's sys.maxint was removed because there is no maximum size for an integer (Python 3's `int` is the same as Python 2's `long`). – asmeurer Sep 24 '14 at 20:58
  • 2
    I'm a bit confused. On my 64 bit Windows system, sys.maxint yields 2^31 -1. – Christofer Ohlsson May 07 '15 at 08:45
  • 1
    @ChristoferOhlsson: You're running a 32-bit Python. – Ignacio Vazquez-Abrams May 07 '15 at 11:26
  • 1
    my sys.maxsize is 9223372036854775807, and it could still represent 9223372036854775807 + 1. I don't understand what sys.maxsize even means. – noɥʇʎԀʎzɐɹƆ Jun 24 '16 at 15:41
  • 2
    @noɥʇʎԀʎzɐɹƆ You were confusing "max int" and "max size". Max size is an amount of bytes. On a 64-bit machine, your virtual memory has 64-bit wide addresses, but we'll leave 1 bit for sign and 1 value for null address, so that gives us 2**63 - 1 addressable bytes. That's 9223372036854775807. A python3 integer is not limited to the 64-bit hardware and can handle (in software) numbers that are bigger than 64-bit. – Johan Boulé Apr 08 '20 at 16:27
  • 1
    Thus if `maxint` was defined on Python 3, it would be `8**sys.maxsize`. – smci May 20 '20 at 05:27
  • I'm not sure the OP cares about the size, just the range, but... I'm boggling that it takes 24 bytes to hold an int64. – Martin Dorey May 27 '21 at 03:35
25

This PEP should help.

Bottom line is that you really shouldn't have to worry about it in python versions > 2.4

mluebke
  • 8,588
  • 7
  • 35
  • 31
  • 23
    You have to worry about it if you have to call a int function in c with something that won't fit in int (i.e. a long). No amount of casting long->int will help. Happened to me just recently. – Macke Sep 25 '12 at 11:38
  • 2
    @Macke: This comment saved me, I assumed that int would do the trick, and was wondering why I was still getting a Jython exception. – ted Oct 25 '12 at 09:44
  • 1
    @Macke Absolutely true. At the company I work at currently we have a Simulator written in Python that takes user input through Tkinter entries and sends the casted values via TCP/IP to a client (written in C/C++) that mimics an embedded system. Imagine what happens when you insert 100000000000000000000000 in your Python-based Entry... :P – rbaleksandar Jul 27 '17 at 08:40
14

Python 2 will automatically set the type based on the size of the value. A guide of max values can be found below.

The Max value of the default Int in Python 2 is 65535, anything above that will be a long

For example:

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

In Python 3 the long datatype has been removed and all integer values are handled by the Int class. The default size of Int will depend on your CPU architecture.

For example:

  • 32 bit systems the default datatype for integers will be 'Int32'
  • 64 bit systems the default datatype for integers will be 'Int64'

The min/max values of each type can be found below:

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

If the size of your Int exceeds the limits mentioned above, python will automatically change it's type and allocate more memory to handle this increase in min/max values. Where in Python 2, it would convert into 'long', it now just converts into the next size of Int.

Example: If you are using a 32 bit operating system, your max value of an Int will be 2147483647 by default. If a value of 2147483648 or more is assigned, the type will be changed to Int64.

There are different ways to check the size of the int and it's memory allocation. Note: In Python 3, using the built-in type() method will always return <class 'int'> no matter what size Int you are using.

James Lane
  • 322
  • 2
  • 5
  • This is the most detailed answer, but I'm not sure it's detailed enough for Python 3 (while Python 2 info can just be deleted). What about the arbitrary-length long? What about using the C-style types directly, eg for porting C code or low-level programming? – Aleksandr Dubinsky Dec 27 '20 at 08:03
  • The maximum value of the default int in Python 2 is not 65535 on my typical 64 bit installation (and Python 2's behavior is still of interest to some of us): `mad@shuttle:~$ python --version; python -c 'print(type(0x7FFFffffFFFFffff))' Python 2.7.16 mad@shuttle:~$ ` – Martin Dorey May 27 '21 at 03:41
  • if Int64 is default, Int8/Int16/Int32 will never be used because Int64 is already larger than them, when Int8/Int16/Int32 are used internally? – harry Dec 27 '21 at 02:56
6

On my machine:

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

Python uses ints (32 bit signed integers, I don't know if they are C ints under the hood or not) for values that fit into 32 bit, but automatically switches to longs (arbitrarily large number of bits - i.e. bignums) for anything larger. I'm guessing this speeds things up for smaller values while avoiding any overflows with a seamless transition to bignums.

MAK
  • 26,140
  • 11
  • 55
  • 86
4

Python 2.7.9 auto promotes numbers. For a case where one is unsure to use int() or long().

>>> a = int("123")
>>> type(a)
<type 'int'>
>>> a = int("111111111111111111111111111111111111111111111111111")
>>> type(a)
<type 'long'>
nvd
  • 2,995
  • 28
  • 16
4

Interesting. On my 64-bit (i7 Ubuntu) box:

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

Guess it steps up to 64 bit ints on a larger machine.

Gringo Suave
  • 29,931
  • 6
  • 88
  • 75
  • 2
    Python uses the larger integer type avaiable for the machine. SO usually on 32-bit machines int will have 32bit size, while on 64 bit-machines it will have 64 bit size. But there could be 32-bit architectures defining 64 bit integers, in that case python would use the 64-bit integer. – Bakuriu Aug 09 '12 at 16:28
2

From python 3.x, the unified integer libraries are even more smarter than older versions. On my (i7 Ubuntu) box I got the following,

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

For implementation details refer Include/longintrepr.h, Objects/longobject.c and Modules/mathmodule.c files. The last file is a dynamic module (compiled to an so file). The code is well commented to follow.

Venki
  • 149
  • 2
  • 6
1

It manages them because int and long are sibling class definitions. They have appropriate methods for +, -, *, /, etc., that will produce results of the appropriate class.

For example

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

In this case, the class int has a __mul__ method (the one that implements *) which creates a long result when required.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
0

Just to continue to all the answers that were given here, especially @James Lanes

the size of the integer type can be expressed by this formula:

total range = (2 ^ bit system)

lower limit = -(2 ^ bit system)*0.5 upper limit = ((2 ^ bit system)*0.5) - 1

Nader Belal
  • 157
  • 3
  • 10