Способы преобразования чисел в разные системы счисления на языке 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 знаков дробь заканчивается раньше.