Skip to content

Latest commit

 

History

History
89 lines (62 loc) · 4.19 KB

File metadata and controls

89 lines (62 loc) · 4.19 KB

int

← Truthy and Falsy · 🏠 Домой · float →


Насколько большим может быть int в Python?

Коротко. Ограничение только по памяти процесса. Переполнения, как в 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).


Какие полезные методы есть у int?

(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 как признак ошибки при вычислении хеша.


Что такое sys.set_int_max_str_digits?

Коротко. Ограничение на длину строкового представления больших чисел — защита от 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 вычислится без проблем, упадёт именно попытка его напечатать.


← Truthy and Falsy · 🏠 Домой · float →