Ответ 1
Помните, что тип Python int
не имеет ограниченного диапазона, как у C int
; единственным ограничением является доступная память.
Память уходит на хранение значения, текущего размера целочисленного хранилища (размер хранилища является переменным для поддержки произвольных размеров) и стандартной бухгалтерии объекта Python (ссылка на соответствующий объект и счетчик ссылок).
Вы можете найти источник longintrepr.h
(тип Python 3 int
традиционно назывался long
типом в Python 2); он эффективно использует тип PyVarObject
C для отслеживания целочисленного размера:
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};
Массив ob_digit
хранит "цифры" шириной 15 или 30 бит (в зависимости от вашей платформы); поэтому в моей 64-битной системе OS X целое число до (2 ^ 30) - 1 использует 1 цифру:
>>> sys.getsizeof((1 << 30) - 1)
28
но если вы используете 2 30-битные цифры в номере, понадобятся дополнительные 4 байта и т.д.:
>>> sys.getsizeof(1 << 30)
32
>>> sys.getsizeof(1 << 60)
36
>>> sys.getsizeof(1 << 90)
40
Основными 24 байтами являются структура PyObject_VAR_HEAD
, содержащая размер объекта, счетчик ссылок и указатель типа (каждые 8 байтов /64 бита на моей 64-битной платформе OS X).
В Python 2 целые числа <= sys.maxint
но> = -sys.maxint - 1
хранятся с использованием более простой структуры, хранящей только одно значение:
typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;
поскольку вместо PyVarObject
используется PyObject
в PyVarObject
нет поля ob_size
а размер памяти ограничен всего 24 байтами; 8 для long
значения, 8 для счетчика ссылок и 8 для указателя объекта типа.