No overflow in variables?

Chris Angelico rosuav at gmail.com
Wed Jan 22 13:26:14 EST 2014


On Thu, Jan 23, 2014 at 5:09 AM, Philip Red
<filippo.biolcati at googlemail.com> wrote:
> Now I do the same with Python:
>
>             x = 9223372036854775807
>             print(type(x))             #   <class 'int'>
>             x = x * 2                  #   18446744073709551614
>             print(x)                   #   <class 'int'>
>             print(type(x))
>
> and I get the right output without overflow and the type is always a 'int'.
> How does Python manages internally the types and their values? Where are they stored?

The Python integer type stores arbitrary precision. It's not a machine
word, like the C# integer types (plural, or does it have only one?
Either way), so it can store any integer you have RAM for. (Which
means, no, Python cannot represent Graham's Number in an int. Sorry
about that.)

Internally, I believe CPython uses the GNU Multiprecision Library
(GMP), which gives an efficient representation and operation format,
scaling to infinity or thereabouts. You can go to any size of integer
you like without there being any difference. There's a cost to that
(even small integers are a bit slower to work with), but it's SO
helpful to be able to work with arbitrarily large numbers that it's
worth that cost.

(Side note: In Python 2, small integers were represented by type 'int'
and those too big to fit into a machine word were automatically
promoted to type 'long'. Python 3 abolished 'int' and renamed 'long'
to 'int', giving what you see here. I'm of the opinion that
small-number arithmetic could be optimized by having small ints stored
as machine words instead of as GMP objects (which could be done
invisibly), but it may be that the complexity isn't worth it.)

I first met arbitrary-precision arithmetic in REXX, back in the 1990s.
It wasn't anything like as efficient as it is now, so for performance
it was important to set the NUMERIC DIGITS setting to just what you
need and no more. Today, thanks to GMP, any high level language should
be able to offer the same as Python does; in fact, I'd consider
infinite-precision integers to be among the fundamental and critical
aspects of any modern high level language (along with object reference
semantics, first-class arrays/mappings/functions/etc, native true
Unicode strings, BSD socket services, and cross-platform support with
a bare minimum of *ix/Win/Mac). There's just no point restricting it
to a machine word, especially since "machine word" varies from machine
to machine.

Incidentally, if you specifically *want* wrap-around behaviour, you
can perform modulo arithmetic. Store everything as unsigned, and after
every operation, take the value modulo 2**64; then for display, if you
need it to be signed, check if it's >= 2**63, and if so, subtract
2**64. (Or use 32, 31, and 32, or whatever word size you want.) That's
a decent simulation of a simple twos-comp integer.

ChrisA



More information about the Python-list mailing list