← Truthy and Falsy · 🏠 Домой · float →
Коротко. Ограничение только по памяти процесса. Переполнения, как в C или
Java, не существует — int произвольной точности встроен в язык.
2 ** 100
# 1267650600228229401496703205376
import sys
sys.maxsize # это НЕ предел int, а максимальный индекс/размер контейнераПодвох. Из-за этого int в Python дороже, чем машинное слово: маленькое
число занимает 28 байт против 8 в C. Там, где важна память под миллионы чисел,
берут array, numpy или bytes.
Глубже. Внутри CPython число хранится массивом «цифр» по 30 бит. Отсюда и квадратичная сложность конвертации в строку для очень больших чисел — см. последний вопрос.
Коротко. // округляет вниз (к минус бесконечности), а знак остатка
совпадает со знаком делителя — не делимого, как в C.
-7 // 2 # -4 (а не -3)
-7 % 2 # 1 (а не -1)
7 % -2 # -1Правило, которое всё объясняет: всегда верно a == (a // b) * b + a % b.
Подвох. Это частый источник расхождений при переносе алгоритмов с других
языков. Если нужно поведение как в C (усечение к нулю), берут
int(a / b) или math.trunc, а для пары «частное и остаток» — divmod(a, b).
(10).bit_length() # 4 — сколько бит нужно для записи
(1000).to_bytes(2, 'big') # b'\x03\xe8'
int.from_bytes(b'\x03\xe8', 'big') # 1000
int('ff', 16) # 255 — разбор в произвольной системе счисленияПолный список — в документации.
Глубже. hash(n) == n для большинства целых, но не для всех: hash(-1)
равен -2, потому что -1 зарезервировано в CPython как признак ошибки при
вычислении хеша.
Коротко. Ограничение на длину строкового представления больших чисел — защита от DoS. По умолчанию 4300 цифр.
python 3.11+, бэкпортировано в security-релизы 3.10.7, 3.9.14, 3.8.14 и
3.7.14. Причина в том, что перевод между int и str имеет квадратичную
сложность: строка на миллион цифр может занять минуты процессорного времени, и
это превращалось в уязвимость там, где число приходит от пользователя.
import sys
sys.set_int_max_str_digits(640)
str(10 ** 700)
# ValueError: Exceeds the limit (640 digits) for integer string conversionПодвох. Ограничение касается только конвертации в строку и обратно. Сама
арифметика с большими числами не ограничена — 10 ** 700 вычислится без
проблем, упадёт именно попытка его напечатать.