Конвертация числовых значений в Python: от двоичного до N-ичного кода

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

Основы перевода чисел в Python

Перевод чисел между системами счисления - одна из базовых задач программирования. Python предлагает как встроенные средства, так и возможности для создания собственных алгоритмов. В этом разделе рассмотрены основные подходы, их достоинства и типичные ошибки.

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

Самый простой и производительный способ - использовать встроенные функции int(), bin(), oct() и hex(). Они работают для оснований 2, 8, 16 и десятичной системы.

# Перевод десятичного числа в двоичную, восьмеричную и шестнадцатеричную системы
number = 255
binary = bin(number)        # '0b11111111'
octal = oct(number)         # '0o377'
hexadecimal = hex(number)   # '0xff'

# Обратное преобразование: из строки с числом в десятичное
int('11111111', 2)  # 255
int('377', 8)       # 255
int('ff', 16)       # 255

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

Типичные ошибки: передача в int() строки с префиксом ('0b', '0o', '0x'). Префиксы нужно удалять, иначе возникнет исключение ValueError. Для преобразования строки с префиксом можно использовать второй аргумент 0 (автоопределение основания): int('0xff', 0) вернёт 255.

Как перевести десятичное число в систему с основанием 2, 8 или 16 с помощью format?

Функция format() и f-строки поддерживают те же основания, что и bin, oct, hex, но позволяют легко управлять шириной поля и выравниванием.

value = 255
print(format(value, 'b'))   # '11111111'
print(format(value, 'o'))   # '377'
print(format(value, 'x'))   # 'ff'
print(f"{value:#010b}")    # '0b11111111' - с префиксом и шириной 10

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

format() не поддерживает произвольные основания (кроме 2, 8, 16). Для систем с основанием от 3 до 36 необходимо использовать ручной алгоритм или библиотеку numpy.

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

Алгоритм последовательного деления на основание с записью остатков в обратном порядке. Для цифр >9 применяются латинские буквы.

def to_base(n, base):
    digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    if n == 0:
        return "0"
    result = ""
    while n > 0:
        result = digits[n % base] + result
        n //= base
    return result

print(to_base(255, 16))   # 'FF'
print(to_base(255, 8))    # '377'
print(to_base(255, 2))    # '11111111'
print(to_base(255, 36))   # '73'

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

Если основание больше 36, алфавит нужно расширять (например, использовать кириллицу). Ошибка: при нулевом значении функция возвращает пустую строку, если не обработать отдельно. Также необходимо учитывать отрицательные числа - для них можно добавить знак после преобразования модуля.

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

Используется полиномиальная формула: каждая цифра умножается на основание в степени позиции.

def from_base(s, base):
    digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    s = s.upper()
    result = 0
    for char in s:
        if char not in digits[:base]:
            raise ValueError(f"Недопустимый символ '{char}' для основания {base}")
        result = result * base + digits.index(char)
    return result

print(from_base("FF", 16))  # 255
print(from_base("73", 36))  # 255

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

Проблемы: регистр символов (поэтому используется s.upper()), пробелы, недопустимые символы. Проверка наличия цифры в алфавите помогает избежать ошибок.

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

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

def frac_to_base(n, base, precision=10):
    """Перевод дробной части n (0 <= n < 1) в указанную систему."""
    digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    result = ""
    for _ in range(precision):
        n *= base
        digit = int(n)
        result += digits[digit]
        n -= digit
        if n == 0:
            break
    return result

def float_to_base(num, base, precision=10):
    """Перевод дробного числа (целая + дробная часть)."""
    integer_part = int(num)
    frac_part = num - integer_part
    int_str = to_base(integer_part, base)
    frac_str = frac_to_base(frac_part, base, precision)
    if frac_str:
        return int_str + "." + frac_str
    else:
        return int_str

print(float_to_base(12.625, 2))   # '1100.101'
print(float_to_base(255.375, 16)) # 'FF.6'

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

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

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

Целая часть переводится по полиномиальной формуле, дробная - делением на основание.

def from_base_float(s, base):
    if '.' in s:
        int_part, frac_part = s.split('.')
    else:
        int_part, frac_part = s, ''
    
    integer_value = from_base(int_part, base)
    frac_value = 0.0
    if frac_part:
        for i, ch in enumerate(frac_part, 1):
            digit = digits.index(ch.upper())
            frac_value += digit / (base ** i)
    return integer_value + frac_value

print(from_base_float("FF.6", 16))  # 255.375

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

Из-за ограниченной точности представления float возможны погрешности при обратном преобразовании.

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

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

import numpy as np
print(np.base_repr(255, base=16))   # 'FF'
print(np.base_repr(255, base=36))   # '73'

Библиотеки увеличивают размер программы. Для простых задач встроенных средств обычно достаточно.

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

Пример 1. Перевод числа 255 во все основные системы с выводом форматированного результата

Пример
number = 255
systems = {'Двоичная': (2, 'b'), 'Восьмеричная': (8, 'o'), 'Шестнадцатеричная': (16, 'x'), '36-ричная': (36, None)}
for name, (base, fmt) in systems.items():
    if fmt:
        result = format(number, fmt)
    else:
        result = to_base(number, base)  # используем ранее определённую функцию
    print(f"{name}: {result}")
Двоичная: 11111111
Восьмеричная: 377
Шестнадцатеричная: ff
36-ричная: 73

Пример 2. Перевод дробного числа 12.625 в двоичную систему с высокой точностью

Пример
def float_to_base_extended(num, base, int_digits=10, frac_digits=20):
    # Аналогично float_to_base, но с настраиваемой точностью
    ...
print(float_to_base_extended(12.625, 2, frac_digits=20))
1100.10100000000000000000

Обратите внимание, что 0.625 в двоичной системе точно представляется как 0.101, поэтому после 101 идут нули.

Пример 3. Использование f-строк для форматирования с префиксами и шириной

Пример
value = 255
print(f"Двоичное: {value:#b}  (ширина 10: {value:#010b})")
print(f"Восьмеричное: {value:#o}")
print(f"Шестнадцатеричное: {value:#x}")
Двоичное: 0b11111111  (ширина 10: 0b11111111)
Восьмеричное: 0o377
Шестнадцатеричное: 0xff

Пример 4. Обработка ошибок при вводе строки с неверными символами

Пример
def safe_from_base(s, base):
    try:
        return int(s, base)
    except ValueError as e:
        print(f"Ошибка: {e}")
        return None

print(safe_from_base("1G", 16))   # G недопустима для 16-ричной
print(safe_from_base("1F", 16))   # 31
Ошибка: invalid literal for int() with base 16: '1G'
31

Пример 5. Перевод большого числа (например, 2^100) в 36-ричную систему

Пример
big = 2**100
print(to_base(big, 36))  # используем функцию to_base
2P0Y5K6Y0P7X5K6Y0P

(результат может отличаться в зависимости от реализации)

Пример 6. Кастомный алфавит для основания 64

Пример
BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
def to_base64(n):
    if n == 0:
        return BASE64_ALPHABET[0]
    result = ""
    while n > 0:
        result = BASE64_ALPHABET[n % 64] + result
        n //= 64
    return result

print(to_base64(255))   # 'D/'
D/

Перевод чисел между системами счисления в Python - comments

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