Detailed Python int type 3 (Why int overflow problem does not exist?)

In previous Python2, the integer divided int and long, that is, integer and long integer, long integer overflow there is no problem that can hold values of any size, supports the theory of infinite numbers.
So Python3, the uniform use of long integer, use an int, there is no long in Python3, only int.

This long int plastic structure is actually very simple, as defined in longintepr.h in:

struct _longobject {
    PyObject_VAR_HEAD
    digit ob_digit[1];
};

It is a ob_digit array pointer. int digit can be considered to be an alias.

Long i.e. Python is internally stored values with an array of int (digit ob_digit [n]). Low value information to be stored is placed in the low index, high standard to compete with the information put in. For example, to save a long 112233445566778899 but our int can only hold 6 (hypothesis):
so will this python store:

ob_digit[0] = 778899;
ob_digit[1] = 445566;
ob_digit[2] = 112233;

Low index stored at low, high-high index located. Examples of the number of sign information stored by the ob_size, like the above object element is 3, and if so ob_size = 3 represents the number is negative, then ob_size = -3

the python integer array structure, each element storing a maximum of 15 bits binary number (the number of bits different operating systems are different 32-bit system memory 15, 30 is a 64-bit system).
The 64-bit system, the maximum number of binary memory 30, i.e., the maximum decimal number is stored in 2 ^ 30-1 = 1,073,741,823, a maximum value of the array element in the example above is stored that is 1,073,741,823.
Then store the digital 10,737,418,231 fact:

ob_digit[0] = 1;
ob_digit[1] = 1073741823;

It should be noted that the actual memory is stored in binary, decimal, rather than what we write.

十进制:1073741823 = 二进制:11111...11111(30位) 存储在高索引 1 

十进制:1 = 二进制:00000...000001(30位) 存储在低索引 0

1 to 2 ^ 30-1 requires a storage array element
2 ^ 30 to 2 ^ 60-1 requires two array elements stored
so ......

Look through the code:

import sys

print("2^30 = {}\n2^60 = {}".format(1024*1024*1024, 1024*1024*1024*1024*1024*1024))

print("0, 1, 2^30-1, 2^30, 2^60-1 的字节大小: ",sys.getsizeof(0), sys.getsizeof(1), sys.getsizeof(1073741823), sys.getsizeof(1073741824), sys.getsizeof(1152921504606846975))

The results are as follows:

2^30 = 1073741824
2^60 = 1152921504606846976
数字 0, 1, 2^30-1, 2^30, 2^60-1,2^60 的字节大小:  24 28 28 32 32 36

Since the Python int a base memory footprint (i.e. the size of the long plastic structure PyObject_VAR_HEAD occupied memory, 24 bytes), and therefore the number 1 to 2 ^ 30-1 memory size is 28 bytes, 2 ^ 30 to 2 ^ 60-1 memory size is 32 bytes, 0 to note here that the memory size is 24 bytes instead of 28 bytes!

The array element with the memory size is four bytes or 32 bits, but in fact valid bit is stored in figures 30 (64-bit system), less two go? ? ?

Actually stored only 30 bits because: exponential computation required to obtain the amount of displacement is a multiple of 5, it may be some kind of optimization algorithm.

See Source:
https://github.com/python/cpython/blob/d8c93aa5d29d3cab537357018d5806a57452a8fe/Include/longintrepr.h#L24
https://github.com/python/cpython/blob/d8c93aa5d29d3cab537357018d5806a57452a8fe/Objects/longobject.c#L4449

Reference article: https://segmentfault.com/a/1190000015284473

Guess you like

Origin www.cnblogs.com/ChangAn223/p/11495690.html