Django-Admin.ru

Числа в Python: int и float

Числа в Python: int и float, преобразование строки в число, деление / и //, остаток %, round и банковское округление, почему 0.1 + 0.2 != 0.3 и Decimal.

Редакция Django-Admin.ru
· обновлено · 8 мин чтения

Содержание · 9 разделов
  1. int: целые числа
  2. Как преобразовать строку в int
  3. float: числа с плавающей точкой
  4. Как преобразовать строку во float
  5. Арифметические операторы
  6. Округление: round, floor, ceil
  7. Почему 0.1 + 0.2 != 0.3
  8. Decimal для денег
  9. Проверка типа и значения числа
  10. Частые ошибки
  11. ValueError: invalid literal for int() with base 10
  12. Сложение строки и числа
  13. Ожидание, что / вернёт int
  14. Сравнение float через ==
  15. Слишком длинное число в строке
  16. Частые вопросы
  17. Как округлить по-школьному, чтобы 2.5 стало 3?
  18. Как разделить целые числа с округлением вверх без math?
  19. Как проверить, что число чётное?
  20. Какое максимальное значение у int?
  21. Есть ли в Python комплексные числа?
  22. Итог

В Python два основных числовых типа: int — целые числа произвольной длины и float — числа с плавающей точкой двойной точности. Короткий ответ: int("42") превращает строку в целое число, float("3.14") — в дробное, деление / всегда возвращает float, а // — целую часть от деления.

Разберём, как создавать числа и преобразовывать строки в int и float, как работают арифметические операторы и округление, почему 0.1 + 0.2 не равно 0.3 и когда вместо float нужен Decimal. Примеры проверены на Python 3.12, вывод показан комментарием # →.

int: целые числа

Тип int хранит целые числа без ограничения по размеру: Python сам выделяет столько памяти, сколько нужно. Переполнения, как в C или Java, не бывает.

print(type(42))      # → <class 'int'>
print(2 ** 100)      # → 1267650600228229401496703205376
print(1_000_000)     # → 1000000 (подчёркивания — для читаемости)
print(0b1010, 0o17, 0xFF)  # → 10 15 255 (двоичная, восьмеричная, шестнадцатеричная запись)

Как преобразовать строку в int

Функция int() принимает строку, число с плавающей точкой или bool. Вторым аргументом можно указать систему счисления:

print(int("42"))        # → 42
print(int(" -7 "))      # → -7 (пробелы по краям допустимы)
print(int("ff", 16))    # → 255
print(int("1010", 2))   # → 10
print(int(3.99))        # → 3
print(int(-3.99))       # → -3

int() от дробного числа отбрасывает дробную часть в сторону нуля, а не округляет. Для округления используйте round() (см. ниже).

Обратные преобразования — bin(10), hex(255) и oct(15) — возвращают строки '0b1010', '0xff' и '0o17'.

float: числа с плавающей точкой

float в Python — это 64-битное число двойной точности по стандарту IEEE 754. Оно хранит примерно 15–17 значащих цифр, а максимальное значение — около 1.8e308.

print(type(42.0), type(4e2))  # → <class 'float'> <class 'float'>
print(1.5, 2., .5)            # → 1.5 2.0 0.5
print(1e3, 2.5e-3)            # → 1000.0 0.0025 (экспоненциальная запись)
print(1e308 * 10)             # → inf

Как преобразовать строку во float

print(float("3.14"))   # → 3.14
print(float("1e-2"))   # → 0.01
print(float(7))        # → 7.0
print(float("inf"), float("-inf"), float("nan"))  # → inf -inf nan

Python понимает только точку как десятичный разделитель. Строку с запятой — частый случай для данных из Excel и форм на русском — сначала исправьте:

float("3,14")                   # → ValueError: could not convert string to float: '3,14'
print(float("3,14".replace(",", ".")))  # → 3.14

Арифметические операторы

ОператорДействиеПримерРезультат
+сложение7 + 29
-вычитание7 - 25
*умножение7 * 214
/деление (всегда float)7 / 23.5
//целочисленное деление7 // 23
%остаток от деления7 % 21
**возведение в степень7 ** 249

Несколько важных правил:

print(6 / 2)          # → 3.0 — даже при делении нацело результат float
print(3 + 2.0)        # → 5.0 — int и float дают float
print(-7 // 2)        # → -4 — округление вниз, а не к нулю
print(-7 % 2)         # → 1 — знак остатка совпадает со знаком делителя
print(divmod(17, 5))  # → (3, 2) — частное и остаток за один вызов
print(2 ** 0.5)       # → 1.4142135623730951

Встроенные функции для чисел: abs(-5) вернёт 5, pow(2, 10) — 1024, pow(2, 10, 1000) — 24 (степень по модулю), max() и min() работают со смесью int и float.

Деление на ноль выбрасывает ZeroDivisionError — и для int, и для float:

1 / 0    # → ZeroDivisionError: division by zero
1.0 / 0  # → ZeroDivisionError: float division by zero

Округление: round, floor, ceil

round(x) округляет до целого и возвращает int, round(x, n) — до n знаков после точки и возвращает float:

print(round(3.14159, 2))  # → 3.14
print(round(1234, -2))    # → 1200
print(round(2.5), round(3.5), round(0.5))  # → 2 4 0
print(round(2.675, 2))    # → 2.67

Два сюрприза в этом примере:

  • Банковское округление. Ровно половина округляется к ближайшему чётному: round(2.5) даёт 2, а round(3.5) — 4. Так снижается накопление ошибки при массовых вычислениях.
  • Неточное представление. Число 2.675 хранится в памяти как чуть меньшее значение, поэтому round(2.675, 2) даёт 2.67, а не 2.68.

Для округления вниз, вверх и отбрасывания дробной части есть модуль math:

import math

print(math.floor(3.7))   # → 3 — вниз
print(math.ceil(3.2))    # → 4 — вверх
print(math.floor(-3.7))  # → -4
print(math.trunc(-3.7))  # → -3 — к нулю, как int()

Если число нужно только показать с двумя знаками, не округляйте его, а отформатируйте при выводе: f"{x:.2f}". Подробнее — в статьях про f-строки и про преобразование числа в строку.

Почему 0.1 + 0.2 != 0.3

print(0.1 + 0.2)          # → 0.30000000000000004
print(0.1 + 0.2 == 0.3)   # → False

Так устроены двоичные числа с плавающей точкой: 0.1 нельзя точно записать в двоичной системе, как 1/3 — в десятичной. Так ведут себя float и double во всех популярных языках.

Сравнивайте float с допуском через math.isclose():

import math

print(math.isclose(0.1 + 0.2, 0.3))  # → True

Decimal для денег

Для денежных расчётов, где важна каждая копейка, используйте Decimal из стандартного модуля decimal. Создавайте его из строки, иначе в него попадёт уже неточное значение float:

from decimal import Decimal

print(Decimal("0.1") + Decimal("0.2"))  # → 0.3
print(Decimal("19.99") * 3)             # → 59.97
print(Decimal(0.1))
# → 0.1000000000000000055511151231257827021181583404541015625

Для точных обыкновенных дробей есть fractions.Fraction: Fraction(1, 3) + Fraction(1, 6) даёт 1/2.

Проверка типа и значения числа

print(isinstance(3, int), isinstance(3.0, float))  # → True True
print((3.0).is_integer(), (3.5).is_integer())      # → True False
print(isinstance(True, int), True + True)          # → True 2

bool — подкласс int, поэтому True ведёт себя как 1, а False — как 0. Если нужно отличить настоящее число от логического значения, проверяйте type(x) is int.

Чтобы проверить, что строка содержит целое число, удобен str.isdigit(), но он вернёт False для "-12" и "3.5". Надёжнее попытаться преобразовать строку и перехватить ошибку — подробнее в статье о try/except:

def to_number(text):
    try:
        return float(text)
    except ValueError:
        return None

print(to_number("-12"), to_number("3.5"), to_number("abc"))  # → -12.0 3.5 None

Частые ошибки

ValueError: invalid literal for int() with base 10

int() получил строку, которая не является целым числом: int("3.14"), int(""), int("12 шт"). Для дробных значений используйте int(float("3.14")), а пустые строки и лишние символы обрабатывайте до преобразования.

Сложение строки и числа

input() всегда возвращает строку, поэтому input("Число: ") + 1 выбросит TypeError. Преобразуйте ввод: int(input("Число: ")).

Ожидание, что / вернёт int

10 / 2 даёт 5.0, а не 5. Если результат используется как индекс списка или аргумент range(), возьмите // или int().

Сравнение float через ==

После вычислений float редко совпадает с «круглым» значением. Используйте math.isclose() или Decimal.

Слишком длинное число в строке

С Python 3.11 (а также начиная с выпусков 3.10.7, 3.9.14, 3.8.14 и 3.7.14) преобразование int в десятичную строку и обратно ограничено 4300 цифрами — это защита от DoS-атак. str(10 ** 5000) выбросит ValueError: Exceeds the limit (4300 digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit. На hex(), bin(), oct() и int(строка, 16) лимит не действует. Если длинные десятичные числа действительно нужны, поднимите лимит через sys.set_int_max_str_digits() или переменную окружения PYTHONINTMAXSTRDIGITS; значение 0 снимает ограничение.

Частые вопросы

Как округлить по-школьному, чтобы 2.5 стало 3?

round() округляет половину к чётному, поэтому для привычного правила возьмите Decimal с режимом ROUND_HALF_UP. Число передавайте строкой:

from decimal import Decimal, ROUND_HALF_UP

print(Decimal("2.5").quantize(Decimal("1"), rounding=ROUND_HALF_UP))       # → 3
print(Decimal("2.675").quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))  # → 2.68

Как разделить целые числа с округлением вверх без math?

Деление // округляет вниз, поэтому для округления вверх меняют знак дважды: -(-a // b). Например, сколько страниц нужно для 7 записей по 2 на странице:

print(-(-7 // 2))  # → 4
print(-(-8 // 2))  # → 4

Результат остаётся точным int даже для очень больших чисел, в отличие от math.ceil(a / b), где промежуточное деление даёт float.

Как проверить, что число чётное?

Остаток от деления на 2 равен нулю: n % 2 == 0. Для отрицательных чисел это тоже работает, потому что остаток в Python имеет знак делителя: -4 % 2 даёт 0, -3 % 2 — 1.

Какое максимальное значение у int?

Предела нет, int ограничен только памятью. sys.maxsize (9223372036854775807 на 64-битных системах) — максимальный размер списков и индексов, а не самого числа. Наибольший float хранится в sys.float_info.max — около 1.8e308.

Есть ли в Python комплексные числа?

Да, встроенный тип complex. Мнимую часть обозначают буквой j:

z = 3 + 4j
print(type(z))           # → <class 'complex'>
print(abs(z))            # → 5.0
print(z.real, z.imag)    # → 3.0 4.0

Математические функции для них — в модуле cmath.

Итог

int хранит целые числа любой длины, float — дробные с ограниченной точностью. Запомните три правила: / всегда возвращает float, round() округляет половину к чётному, а сравнивать float нужно через math.isclose(); для денег берите Decimal. Другие встроенные типы описаны в статье о переменных и типах данных, а весь синтаксис языка — в шпаргалке по Python.

  • #Python
  • #int
  • #float
  • #Числа
  • #Синтаксис
↑ ↓ выборEnter открытьEsc закрыть