开发者

How does Python manage int and long?

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


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.


This PEP should help.

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


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.


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.


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.


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


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.


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜