Функции перевода систем счисления в Python

Раздел: Основы Python -> Перевод систем счисления

Основные подходы к переводу систем счисления

Универсальная функция для перевода целых чисел в систему с произвольным основанием (2–36)

Наиболее эффективное и гибкое решение – реализовать собственную функцию, которая принимает число и основание и возвращает строку. Алгоритм основан на последовательном делении числа на основание с сохранением остатков. Остатки преобразуются в символы (0–9, A–Z). Результат собирается в обратном порядке.

def dec_to_base(n, base):
    if not isinstance(n, int):
        raise TypeError("Число должно быть целым")
    if not (2 <= base <= 36):
        raise ValueError("Основание от 2 до 36")
    if n == 0:
        return "0"
    negative = n < 0
    n = abs(n)
    digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    res = []
    while n > 0:
        res.append(digits[n % base])
        n //= base
    if negative:
        res.append('-')
    return ''.join(reversed(res))

print(dec_to_base(255, 16))  # FF
print(dec_to_base(-255, 2))  # -11111111
print(dec_to_base(100, 36))  # 2S

Python восьмеричная система (восьмеричная система счисления в python)

FF
-11111111
2S

перевод в другие системы счисления python (перевод в другую систему счисления в python)

Функция корректно обрабатывает ноль, отрицательные числа и выбрасывает исключения при неверных аргументах. Основные проблемы: ограничение алфавита до 36 символов, невозможность перевода дробных чисел.

Как перевести число в двоичную, восьмеричную или шестнадцатеричную систему с помощью встроенных средств?

Для базовых систем (2, 8, 16) Python предоставляет функции bin(), oct(), hex() и метод format().

n = 255
print(bin(n))   # 0b11111111
print(oct(n))   # 0o377
print(hex(n))   # 0xff
# Чистое представление без префикса:
print(format(n, 'b'))   # 11111111
print(format(n, 'o'))   # 377
print(format(n, 'x'))   # ff
print(format(n, 'X'))   # FF

16 система счисления python (перевод в шестнадцатеричную систему в python)

0b11111111
0o377
0xff
11111111
377
ff
FF

Python перевод в двоичную систему (перевод числа в двоичную систему в python)

Типичные ошибки:

  • Использование format с неподдерживаемым кодом формата (например, 't' для троичной) вызовет ValueError.
  • Забывание, что bin() возвращает строку с префиксом "0b". Для извлечения числа без префикса применяют срез.
  • Попытка использовать int() с основанием >36 – будет ошибка.

Как перевести число из любой системы счисления (2–36) обратно в десятичную?

Функция int() с указанием основания позволяет получить десятичное целое из строки.

s = "FF"
print(int(s, 16))  # 255
s2 = "1010"
print(int(s2, 2))  # 10
s3 = "2S"
print(int(s3, 36)) # 100
# Отрицательное число
print(int("-FF", 16)) # -255

перевод в десятичную систему счисления python (перевод числа в десятичную систему счисления в python)

255
10
100
-255

перевод в троичную систему python (перевод числа в троичную систему в python)

Ошибка возникает, если строка содержит символы, недопустимые для данного основания. Например, int("GG", 16) вызовет ValueError. Также основание должно быть от 2 до 36. Для больших оснований int не применим.

Можно ли реализовать перевод рекурсивно?

Рекурсивная версия возможна, но менее эффективна из-за ограничений глубины рекурсии. Пример:

def dec_to_base_rec(n, base):
    if n == 0:
        return ""
    rem = n % base
    digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    return dec_to_base_rec(n // base, base) + digits[rem]

print(dec_to_base_rec(255, 16))     # FF
print(dec_to_base_rec(0, 2))        # пустая строка – требуется доработка для нуля

функция перевода систем счисления python (функция перевода в любую систему счисления в python)

FF
(пустая строка)

Главная проблема – отсутствие обработки нуля и возможное переполнение стека для больших чисел (например, 10^6 в двоичной системе потребует около 20 рекурсий, что допустимо, но 10^100 – уже нет). Рекурсивный метод проще, но менее надёжен.

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

Для дробей алгоритм разделяет целую и дробную части. Целая часть переводится делением, дробная – умножением на основание с выделением целых частей. Пример для числа 10.125 в двоичную:

def dec_to_base_frac(n, base, precision=10):
    # n – float, base – основание, precision – количество знаков после запятой
    if base < 2 or base > 36:
        raise ValueError("Основание от 2 до 36")
    integer_part = int(n)
    frac_part = n - integer_part
    # перевод целой части
    int_str = dec_to_base(integer_part, base)  # из предыдущей функции
    # перевод дробной части
    digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    frac_str = []
    for _ in range(precision):
        frac_part *= base
        digit = int(frac_part)
        frac_str.append(digits[digit])
        frac_part -= digit
        if frac_part == 0:
            break
    if frac_str:
        return int_str + "." + ''.join(frac_str)
    else:
        return int_str

print(dec_to_base_frac(10.125, 2))    # 1010.001
print(dec_to_base_frac(0.1, 3, 5))    # 0.00220 (приблизительно)
1010.001
0.00220

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

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

Когда стандартного набора символов (0–9, A–Z) не хватает, используют расширенный алфавит. Для base64 применяют 64 символа: A–Z, a–z, 0–9, +, /. Пример реализации:

BASE64_ALPH = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

def dec_to_base64(n):
    if n == 0:
        return BASE64_ALPH[0]
    res = []
    while n > 0:
        res.append(BASE64_ALPH[n % 64])
        n //= 64
    return ''.join(reversed(res))

print(dec_to_base64(123456))  # eJI
eJI

При использовании нестандартных алфавитов нужно явно задать порядок символов. Обратный перевод потребует своей функции, так как int() не поддерживает основания >36. Кроме того, при смене алфавита результаты могут отличаться от стандартных base64-кодировок (например, в кодировке Base64 используется padding, но здесь это просто система счисления).

Практические примеры

Пример 1. Полная функция перевода в любую систему (2–36) с проверками

Функция поддерживает отрицательные числа, ноль, выбрасывает исключения при неверных аргументах. Удобна для использования в проектах.

Пример
def dec_to_base_full(n, base):
    if not isinstance(n, (int, float)):
        raise TypeError("Число должно быть числовым типом")
    if not (2 <= base <= 36):
        raise ValueError("Основание должно быть от 2 до 36")
    if n == 0:
        return "0"
    negative = n < 0
    n = abs(int(n))
    digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    res = []
    while n > 0:
        res.append(digits[n % base])
        n //= base
    if negative:
        res.append('-')
    return ''.join(reversed(res))

print(dec_to_base_full(0, 2))        # 0
print(dec_to_base_full(1000, 36))    # RS
print(dec_to_base_full(-255, 16))    # -FF
0
RS
-FF

Пример 2. Функция для перевода из любой системы (2–36) в десятичную

Аналог int(), но с дополнительной проверкой алфавита.

Пример
def base_to_dec(s, base):
    if not (2 <= base <= 36):
        raise ValueError("Основание от 2 до 36")
    s = s.strip()
    if not s:
        raise ValueError("Пустая строка")
    negative = s[0] == '-'
    if negative:
        s = s[1:]
    digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    value = 0
    for ch in s:
        ch = ch.upper()
        if ch not in digits[:base]:
            raise ValueError(f"Неверный символ '{ch}' для основания {base}")
        value = value * base + digits.index(ch)
    if negative:
        value = -value
    return value

print(base_to_dec("FF", 16))    # 255
print(base_to_dec("2S", 36))    # 100
print(base_to_dec("-1111", 2))  # -15
255
100
-15

Пример 3. Перевод дробного числа с настраиваемой точностью

Используется на практике для вычислений в нестандартных системах счисления.

Пример
def dec_to_frac_base(n, base, precision=8):
    if base < 2 or base > 36:
        raise ValueError("Основание от 2 до 36")
    integer = int(n)
    frac = n - integer
    int_str = dec_to_base_full(integer, base)
    digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    frac_parts = []
    for _ in range(precision):
        frac *= base
        d = int(frac)
        frac_parts.append(digits[d])
        frac -= d
        if abs(frac) < 1e-12:
            break
    if frac_parts:
        return int_str + "." + ''.join(frac_parts)
    return int_str

print(dec_to_frac_base(3.14159, 16, 6))    # 3.243F6C
print(dec_to_frac_base(0.1, 3, 5))         # 0.00220
3.243F6C
0.00220

Пример 4. Представление двоичного числа через битовые операции

Полезно для понимания внутреннего представления чисел.

Пример
def bin_shift(n):
    if n == 0:
        return "0"
    res = []
    while n:
        res.append('1' if n & 1 else '0')
        n >>= 1
    return ''.join(reversed(res))

print(bin_shift(255))   # 11111111
print(bin_shift(1024))  # 10000000000
11111111
10000000000

Пример 5. Система с основанием 64 (нестандартный алфавит)

Используется для компактного представления чисел. Важно согласовывать алфавит.

Пример
ALPH64 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-"

def dec_to_base64_custom(n):
    if n == 0:
        return ALPH64[0]
    res = []
    while n > 0:
        res.append(ALPH64[n % 64])
        n //= 64
    return ''.join(reversed(res))

def base64_to_dec(s):
    value = 0
    for ch in s:
        value = value * 64 + ALPH64.index(ch)
    return value

# пример
c = dec_to_base64_custom(123456789)
print(c)                              # 1Q7F1
print(base64_to_dec(c))               # 123456789
1Q7F1
123456789

Пример 6. Интерактивный конвертер с вводом данных

Позволяет пользователю выбрать направление перевода.

Пример
def converter():
    print("Конвертер систем счисления")
    mode = input("Выберите режим: 1 - из десятичной в любую, 2 - из любой в десятичную: ")
    if mode == "1":
        n = input("Введите число: ")
        b = int(input("Основание (2-36): "))
        try:
            result = dec_to_base_full(int(n), b)
            print(f"Результат: {result}")
        except Exception as e:
            print(f"Ошибка: {e}")
    elif mode == "2":
        s = input("Введите число в строковой форме: ")
        b = int(input("Основание (2-36): "))
        try:
            result = base_to_dec(s, b)
            print(f"Результат: {result}")
        except Exception as e:
            print(f"Ошибка: {e}")
    else:
        print("Неверный режим")

# Пример запуска (закомментирован в реальном коде)
# converter()
(При запуске будет интерактивный диалог)

Функция перевода в любую систему счисления в Python - comments

En
функция перевода систем счисления python (python)