Как Python управляет int и long?

118

Кто-нибудь знает, как Python управляет внутренними типами int и long?

  • Подбирает ли он правильный тип динамически?
  • Какой предел для int?
  • Я использую Python 2.6, отличается ли он от предыдущих версий?

Как мне понять приведенный ниже код?

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

Обновить:

>>> print type(0x7fffffff)
<type 'int'>
>>> print type(0x80000000)
<type 'long'>
Luc
источник
Разве они не просто сопоставляются с типами stdc на лету в CPython?
Aiden Bell
Да, думаю, да. Я также подозреваю, что все размещено в куче, поэтому, когда число требует большей точности, у reallocних все в порядке. Но я не совсем уверен, поэтому оставлю ответ кому-нибудь другому.
zneak
2
Вы также можете заставить python использовать длинную переменную с помощьюvar = 666L
qba
8
@Ignacio: НЕПРАВИЛЬНО CPython int- это C long(по умолчанию подписан) ... см . <CPython 2.X source>/Include/intobject.h: typedef struct {PyObject_HEAD long ob_ival; } PyIntObject; В любом случае Python 2.x intдопускает отрицательные числа; C unsignedпросто не справился бы.
Джон Мачин,
PEP 237 обсуждает, как под капотом Python предназначен для того, чтобы все это выглядело одинаково.
Carel

Ответы:

124

intи longбыли "унифицированы" несколько версий назад . До этого можно было переполнить int через математические операции.

3.x продвинулся дальше, полностью исключив long и сохранив только int.

  • Python 2 : sys.maxintсодержит максимальное значение, которое может содержать Python int.
    • На 64-битном Python 2.7 размер составляет 24 байта. Проверить с sys.getsizeof().
  • Python 3 : sys.maxsizeсодержит максимальный размер в байтах, который может быть Python int.
    • Это будут гигабайты в 32-битном формате и эксабайты в 64-битном формате.
    • Такой большой int будет иметь значение, подобное 8 в степени sys.maxsize.
Игнасио Васкес-Абрамс
источник
30
Но Python3 называет этот тип int, хотя он больше похож на long в версии 2.x.
3
Комментарий Теда: как упоминалось ниже, помните, что приведение к типу int значения, большего, чем maxint, все равно приведет к длинному >>> type (int (sys.maxint + 1)) <type 'long'>
StuartLC
2
sys.maxint даст вам наибольшее 64-битное целое число (на моей 64-битной машине). Long может быть намного больше, чем 64-битное, просто попробуйте "sys.maxint << 1000000"
fccoelho
4
В python3 это sys.maxsize
pylover
3
sys.maxsize не имеет ничего общего с целыми числами. Python 3 sys.maxint был удален, потому что не существует максимального размера для целого числа (Python 3 intтакой же, как Python 2 long).
asmeurer
19

Этот PEP должен помочь.

Суть в том, что вам действительно не нужно беспокоиться об этом в версиях python> 2.4

mluebke
источник
15
Вы должны беспокоиться об этом, если вам нужно вызвать функцию int в c с чем-то, что не подходит для int (например, long). Никакое приведение типа long-> int не поможет. Со мной случилось совсем недавно.
Macke
1
@Macke: этот комментарий меня спас, я предположил, что int поможет, и мне было интересно, почему я все еще получаю исключение Jython.
ted
@Macke Абсолютно верно. В компании, в которой я работаю, в настоящее время есть симулятор, написанный на Python, который принимает вводимые пользователем данные через записи Tkinter и отправляет приведенные значения через TCP / IP клиенту (написанному на C / C ++), который имитирует встроенную систему. Представьте, что происходит, когда вы вставляете 100000000000000000000000 в свою запись на основе Python ...: P
rbaleksandar
@Mackie хорошо, если вы действительно удосужились прочитать PEP, он прямо говорит: C API остается неизменным; Код на C по-прежнему должен учитывать разницу между короткими и длинными целыми числами. (API Python 3.0 C, вероятно, будет полностью несовместим.) API PyArg_Parse * () уже принимают длинные целые числа, если они находятся в пределах диапазона, представляемого целыми или длинными числами C, поэтому функции, принимающие C int или длинный аргумент, выиграли ' Не нужно беспокоиться о работе с лонгами Python.
Cowbert
4

На моей машине:

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

Python использует целые числа (32-битные целые числа со знаком, я не знаю, являются ли они целыми числами C под капотом или нет) для значений, которые вписываются в 32-битные значения, но автоматически переключается на longs (произвольно большое количество бит - т.е. bignums) для чего угодно больше. Я предполагаю, что это ускоряет работу с меньшими значениями, избегая любых переполнений с плавным переходом на большие значения.

MAK
источник
4

Интересный. В моем 64-битном (i7 Ubuntu) поле:

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

Угадайте, что на большей машине он увеличивает до 64 бит.

Гринго Вежливый
источник
2
Python использует больший целочисленный тип, доступный для машины. SO обычно на 32-битных машинах int будет иметь 32-битный размер, а на 64-битных машинах он будет иметь 64-битный размер. Но могут быть 32-битные архитектуры, определяющие 64-битные целые числа, в этом случае python будет использовать 64-битные целые числа.
Бакуриу
4

Python 2.7.9 автоматически продвигает числа. Для случая, когда вы не уверены в использовании int () или long ().

>>> a = int("123")
>>> type(a)
<type 'int'>
>>> a = int("111111111111111111111111111111111111111111111111111")
>>> type(a)
<type 'long'>
ПНВ
источник
4

Python 2 автоматически установит тип в зависимости от размера значения. Руководство по максимальным значениям можно найти ниже.

Максимальное значение Int по умолчанию в Python 2 - 65535, все, что выше, будет длинным.

Например:

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

В Python 3 длинный тип данных был удален, и все целочисленные значения обрабатываются классом Int. Размер Int по умолчанию будет зависеть от архитектуры вашего процессора.

Например:

  • В 32-битных системах тип данных по умолчанию для целых чисел будет Int32.
  • В 64-битных системах типом данных по умолчанию для целых чисел будет Int64.

Минимальные / максимальные значения каждого типа можно найти ниже:

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

Если размер вашего Int превышает указанные выше ограничения, python автоматически изменит его тип и выделит больше памяти для обработки этого увеличения минимальных / максимальных значений. Если в Python 2 он преобразовывался в long, теперь он просто преобразуется в следующий размер Int.

Пример: если вы используете 32-битную операционную систему, максимальное значение Int по умолчанию будет 2147483647. Если присвоено значение 2147483648 или более, тип будет изменен на Int64.

Есть разные способы проверить размер int и выделение памяти. Примечание. В Python 3 использование встроенного метода type () всегда будет возвращать, <class 'int'>независимо от того, какой размер Int вы используете.

Джеймс Лейн
источник
1

Начиная с python 3.x, унифицированные целочисленные библиотеки даже умнее, чем старые версии. В моем (i7 Ubuntu) я получил следующее:

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

За подробностями реализации обратитесь к Include/longintrepr.h, Objects/longobject.c and Modules/mathmodule.cфайлам. Последний файл - это динамический модуль (скомпилированный в файл so). Код хорошо прокомментирован.

Venki
источник
1

Просто продолжу все ответы, которые были здесь даны, особенно @James Lanes

размер целочисленного типа может быть выражен этой формулой:

общий диапазон = (2 ^ битная система)

нижний предел = - (2 ^ битовая система) * 0,5 верхний предел = ((2 ^ битовая система) * 0,5) - 1

Надер Белал
источник
0

Он управляет ими, потому что intи longявляются определениями родственных классов. У них есть соответствующие методы для +, -, *, / и т. Д., Которые будут давать результаты соответствующего класса.

Например

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

В этом случае у класса intесть __mul__метод (тот, который реализует *), который longпри необходимости создает результат.

С. Лотт
источник