Функции перевода систем счисления в 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)) # 2SPython восьмеричная система (восьмеричная система счисления в 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')) # FF16 система счисления 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()
(При запуске будет интерактивный диалог)