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

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

Реализация перевода чисел в системы счисления

Наиболее эффективное решение

Универсальная функция перевода целого числа в любую систему с основанием от 2 до 36 (цифры 0-9, A-Z) строится на последовательном делении числа на основание. Остатки от деления, взятые в обратном порядке, образуют искомую запись.

def to_base(num: int, base: int) -> str:
    digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    if num == 0:
        return '0'
    result = ''
    while num > 0:
        result = digits[num % base] + result
        num //= base
    return result

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

Пояснение шагов:

  • digits - строка, содержащая все возможные символы для систем с основанием до 36.
  • Если число равно нулю, сразу возвращается '0'.
  • Пока число больше нуля, извлекается остаток от деления на основание, по индексу из digits находится соответствующий символ и добавляется слева к результирующей строке.
  • Число целочисленно делится на основание (отбрасывается дробная часть).

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

  • Ошибка: попытка использовать отрицательное число без обработки знака. Решение: обработать знак отдельно (см. один из вариантов ниже).
  • Ошибка: передача основания больше 36 - символы закончатся. Решение: расширить набор символов (например, добавить строчные буквы) или использовать пользовательский алфавит.
  • Ошибка: забыть обработать случай num == 0 - функция вернёт пустую строку. Решение: явное условие на ноль.

Цель и случаи использования

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

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

В Python есть встроенные функции bin(), oct(), hex(). Они возвращают строку с префиксами '0b', '0o', '0x' соответственно.

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

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

Проблема и решение

Эти функции работают только для оснований 2, 8, 16. Для других оснований потребуется собственная реализация. Префиксы можно удалить срезом: bin(num)[2:].

Цель и случаи использования

Быстрое получение записи в часто используемых системах счисления, особенно при отладке (вывод в hex) или работе с битовыми масками.

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

Рекурсивная функция вызывает саму себя с уменьшенным числом, а затем добавляет символ для текущего остатка.

def to_base_rec(num: int, base: int) -> str:
    digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    if num < base:
        return digits[num]
    else:
        return to_base_rec(num // base, base) + digits[num % base]

print(to_base_rec(100, 16))  # 64

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

Возможные проблемы

  • Глубина рекурсии может быть превышена для очень больших чисел (в Python по умолчанию ~1000). Решение: использовать итеративный подход.
  • Для нуля рекурсивная функция выдаст ошибку (базовый случай не сработает). Решение: добавить проверку if num == 0: return '0'.

Цель и случаи использования

Рекурсия делает код более лаконичным и наглядным, подходит для обучения алгоритмам или преобразования чисел небольшой величины.

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

Отрицательное число обычно представляется со знаком минус. Алгоритм: взять модуль числа, перевести его и добавить знак.

def to_base_signed(num: int, base: int) -> str:
    if num < 0:
        return '-' + to_base(abs(num), base)  # используем предыдущую функцию
    else:
        return to_base(num, base)

print(to_base_signed(-255, 16))  # -FF

шестнадцатеричная система счисления python (шестнадцатеричная система счисления в python)

Особенности

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

Цель и случаи использования

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

Как перевести дробные числа?

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

def to_base_frac(num: float, base: int, precision: int = 10) -> str:
    integer_part = int(num)
    fractional_part = num - integer_part
    res_int = to_base(integer_part, base)  # используем целочисленную функцию
    if fractional_part == 0:
        return res_int
    res = res_int + '.'
    for _ in range(precision):
        fractional_part *= base
        digit = int(fractional_part)
        res += digits[digit]
        fractional_part -= digit
        if fractional_part == 0:
            break
    return res

digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
print(to_base_frac(12.375, 2, 10))  # 1100.011

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

  • Для многих дробей невозможно получить точное представление (периодическая дробь). Решение: ограничить точность или обнаруживать период.
  • Погрешность при умножении из-за чисел с плавающей точкой. Решение: использовать Decimal из модуля decimal для точной арифметики.

Цель и случаи использования

Необходимо при переводе вещественных чисел в системы счисления, отличные от десятичной, например, при работе с шестнадцатеричными дампами или двоичным представлением чисел.

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

Библиотека numpy содержит функцию numpy.base_repr, которая переводит целое число в строку для основания от 2 до 36. Для более широкого набора символов нужно задать свой алфавит.

import numpy as np
print(np.base_repr(255, 16))   # FF
print(np.base_repr(100, 3))    # 10201

Ограничения

Функция не обрабатывает дробные числа и отрицательные числа (только беззнаковые). Требуется установка NumPy. Решение: для разовых простых задач можно обойтись встроенными средствами.

Цель и случаи использования

Удобство при работе в средах, где NumPy уже установлен (научные расчёты), особенно когда требуется быстрое преобразование большого количества чисел.

Расширенные примеры перевода чисел

Пример 1: Перевод большого целого числа в шестнадцатеричную систему

Пример
def to_base(num: int, base: int) -> str:
    digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    if num == 0:
        return '0'
    result = ''
    while num > 0:
        result = digits[num % base] + result
        num //= base
    return result

big_num = 12345678901234567890
hex_val = to_base(big_num, 16)
print(hex_val)
AB54A98CEB1F0AD2

Пояснение: Функция последовательно делит большое число на 16, остатки формируют шестнадцатеричное представление. Результат занимает 16 символов, что компактнее десятичной записи.


Пример 2: Перевод в систему с основанием 60 (с пользовательским алфавитом)

Пример
def to_base_custom(num: int, base: int, alphabet: str) -> str:
    if num == 0:
        return alphabet[0]
    result = ''
    while num > 0:
        result = alphabet[num % base] + result
        num //= base
    return result

alphabet_60 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'  # 10+26+26 = 62 символа, используем первые 60
print(to_base_custom(123456, 60, alphabet_60[:60]))
A0Gq

Пояснение: Поскольку стандартный набор символов ограничен 36, для основания 60 создаётся собственный алфавит из 60 символов (цифры, заглавные и строчные буквы). Функция работает аналогично.


Пример 3: Перевод из одной произвольной системы в другую

Пример
def from_base(num_str: str, base_from: int) -> int:
    digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    num = 0
    for char in num_str.upper():
        num = num * base_from + digits.index(char)
    return num

def to_base(num: int, base_to: int) -> str:
    digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    if num == 0:
        return '0'
    result = ''
    while num > 0:
        result = digits[num % base_to] + result
        num //= base_to
    return result

# Перевести число из 3-чной системы в 5-чную
num_in_3 = '210'
decimal = from_base(num_in_3, 3)
num_in_5 = to_base(decimal, 5)
print(f'{num_in_3} (base 3) = {num_in_5} (base 5)')
210 (base 3) = 103 (base 5)

Пояснение: Сначала число из исходной системы преобразуется в десятичное число (from_base), затем десятичное число переводится в целевую систему (to_base). Этот метод универсален.


Пример 4: Перевод отрицательного числа в восьмеричную систему

Пример
def to_base_signed(num: int, base: int) -> str:
    digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    if num < 0:
        sign = '-'
        num = -num
    else:
        sign = ''
    if num == 0:
        return sign + '0'
    result = ''
    while num > 0:
        result = digits[num % base] + result
        num //= base
    return sign + result

print(to_base_signed(-1234, 8))
-2322

Пояснение: Знак сохраняется отдельно, модуль числа переводится обычным способом. Результат содержит минус перед восьмеричной записью.


Пример 5: Перевод дробного числа в двоичную систему с точностью 5 знаков

Пример
def to_base_frac(num: float, base: int, precision: int = 5) -> str:
    digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    integer_part = int(num)
    fractional_part = num - integer_part
    res_int = '' if integer_part == 0 else ''
    # перевод целой части
    if integer_part == 0:
        res_int = '0'
    else:
        tmp = integer_part
        while tmp > 0:
            res_int = digits[tmp % base] + res_int
            tmp //= base
    if fractional_part == 0:
        return res_int
    res = res_int + '.'
    for _ in range(precision):
        fractional_part *= base
        digit = int(fractional_part)
        res += digits[digit]
        fractional_part -= digit
        if fractional_part == 0:
            break
    return res

print(to_base_frac(10.625, 2, 5))
1010.101

Пояснение: Целая часть 10₁₀ = 1010₂, дробная 0.625. Последовательно: 0.625*2 = 1.25 → 1; 0.25*2 = 0.5 → 0; 0.5*2 = 1.0 → 1. Получено 101.101₂. При точности 5 знаков дробь заканчивается раньше.

Перевод числа в любую систему счисления на Python (код) - comments

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