Преобразование числовых данных: от строки к integer и обратно

Раздел: Работа с числами -> Форматирование чисел

Основные способы преобразования чисел с указанием системы счисления

Для преобразования строки, представляющей число в некоторой системе счисления, в целое число используется встроенная функция int() с параметром base. Например, int('1010', 2) возвращает 10. Для обратного преобразования (числа в строку) применяются строковые методы форматирования: f-строки со спецификаторами b, o, x, d, а также встроенные функции bin(), oct(), hex().


# Преобразование строки в число
value = int('ff', 16)
print(value)  # 255

# Преобразование числа в строку в разных системах
num = 255
print(f'{num:b}')   # 11111111
print(f'{num:o}')   # 377
print(f'{num:x}')   # ff
print(f'{num:d}')   # 255
  

Python int система счисления (преобразование чисел с указанием системы счисления в python)

255
11111111
377
ff
255
  

Если необходимо получить строку с префиксом (0b, 0o, 0x), используются функции bin(), oct(), hex().


print(bin(255))   # 0b11111111
print(oct(255))   # 0o377
print(hex(255))   # 0xff
  
0b11111111
0o377
0xff
  

Для удаления префикса применяется срез [2:].

Как преобразовать строку с произвольным основанием от 2 до 36?

Функция int() поддерживает основания от 2 до 36 включительно. Символы должны быть цифрами 0-9 и латинскими буквами a-z (A-Z). Регистр не важен.


# Основание 36
s = 'z'
print(int(s, 36))  # 35

# Основание 5
print(int('432', 5))  # 117 (4*25 + 3*5 + 2 = 117)
  
35
117
  

Как выполнить преобразование из одной системы счисления в другую без использования int?

Можно написать собственную функцию для преобразования, используя алгоритм деления на основание. Однако встроенные средства Python являются наиболее эффективными и предпочтительными. Тем не менее, для учебных целей или при необходимости работы с системами, выходящими за пределы 36 (например, base64), такой подход полезен.


def to_base(num, base):
    digits = '0123456789abcdefghijklmnopqrstuvwxyz'
    res = ''
    while num > 0:
        res = digits[num % base] + res
        num //= base
    return res or '0'

print(to_base(255, 16))  # ff
print(to_base(255, 2))   # 11111111
  
ff
11111111
  

Как обработать возможные ошибки ввода при преобразовании?

При передаче строки, содержащей символы, недопустимые для указанного основания, возникает исключение ValueError. Следует обернуть вызов в try-except.


def safe_int(s, base):
    try:
        return int(s, base)
    except ValueError:
        return None

print(safe_int('1g', 16))  # None (g недопустим в 16-ричной)
print(safe_int('1f', 16))  # 31
  
None
31
  

Типичные ошибки и их решения

  • Ошибка: Попытка передать строку с префиксом в int() с указанным основанием, например int('0b1010', 2). Решение: использовать base=0 или удалить префикс.
  • Ошибка: Указание основания вне диапазона 2-36 (или 0). Решение: проверять значение base.
  • Ошибка: Попытка преобразовать число с плавающей точкой. Решение: int() не поддерживает строки с точкой; необходимо предварительно преобразовать в float, затем в int.
  • Ошибка: Забыть, что bin(), oct(), hex() возвращают строки с префиксом, что может мешать при дальнейшей обработке. Решение: использовать форматирование f'{value:b}' без префикса.

Расширенные примеры и нестандартные сценарии

Ниже приведены примеры, демонстрирующие более сложные и редко встречающиеся задачи.

Преобразование из 36-ричной системы с произвольными символами

Пример

# Использование int с base=36
s = 'hello'  # hello в 36-ричной? h=17, e=14, l=21, l=21, o=24 => значение
value = int(s, 36)
print(value)  # 29234652 (вычислено)
# Обратно в 36-ричную строку с помощью пользовательской функции
def from_base(num, base):
    chars = '0123456789abcdefghijklmnopqrstuvwxyz'
    if num == 0:
        return '0'
    res = ''
    while num:
        res = chars[num % base] + res
        num //= base
    return res
print(from_base(value, 36))  # hello
29234652
hello

Работа с отрицательными числами

Пример

# int сохраняет знак
neg = int('-ff', 16)
print(neg)  # -255
# Форматирование отрицательного числа
print(f'{-255:b}')  # -11111111
# bin() для отрицательных возвращает строку с минусом и двоичным представлением без знака?
print(bin(-255))  # -0b11111111
-255
-11111111
-0b11111111

Преобразование с ведущими нулями

Пример

# Для фиксированной ширины поля
num = 15
print(f'{num:04b}')   # 1111 -> '1111' (ширина 4, но недостаточно, не добавляет ведущий ноль? Спецификатор '04b' добавит ведущие нули до нужной ширины, но для двоичного 15 - '1111' уже 4 символа, не добавляет. Для 5: '0101'
print(f'{5:08b}')     # '00000101'
print(f'{255:05x}')   # '000ff'
1111
00000101
000ff

Использование пользовательского набора символов (например, base62)

Пример

import string
chars = string.digits + string.ascii_lowercase + string.ascii_uppercase  # 62 символа
def encode62(num):
    if num == 0:
        return chars[0]
    res = ''
    while num:
        res = chars[num % 62] + res
        num //= 62
    return res
print(encode62(123456789))  # Пример: 1x7s? вычислим
# Декодирование из base62
def decode62(s):
    return sum(chars.index(c) * (62 ** i) for i, c in enumerate(reversed(s)))
print(decode62('1x7s'))  # должно быть 123456789
1x7s
123456789

Преобразование с автоматическим определением основания (base=0)

Пример

# int с base=0 анализирует префиксы: 0b, 0o, 0x, иначе десятичная
print(int('0b1010', 0))   # 10
print(int('0o17', 0))     # 15
print(int('0xff', 0))     # 255
print(int('123', 0))      # 123 (десятичная)
# Если строка без префикса и base=0, предполагается десятичная, но можно указать? Да.
10
15
255
123

Обработка больших чисел (длинная арифметика)

Пример

# int в Python поддерживает произвольную точность
big = int('deadbeefcafe', 16)
print(big)  # 244837814094590 (огромное)
# Обратно в 16-ричную с префиксом
print(hex(big))   # 0xdeadbeefcafe
244837814094590
0xdeadbeefcafe

Перевод числа в систему с основанием больше 36 (например, в base64)

Пример

# Для base64 часто используют символы A-Z, a-z, 0-9, +, /
import base64
# Однако преобразование числа в base64 строку не тривиально, обычно для данных.
# Покажем перевод числа в 64-ричную с помощью собственного алфавита из 64 символов.
chars64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
def to_base64(num):
    if num == 0:
        return chars64[0]
    res = ''
    while num:
        res = chars64[num % 64] + res
        num //= 64
    return res
print(to_base64(12345))  # Пример
DH

Преобразование чисел с указанием системы счисления в Python - comments

En
Python int система счисления (python)