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

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

Основы восьмеричной системы счисления в Python

Восьмеричная система (основание 8) используется в некоторых областях программирования, например, при работе с правами доступа в Unix-системах или при отладке бинарных протоколов. Python предоставляет встроенные средства для работы с восьмеричными числами: литералы, функции преобразования и форматирования.

Наиболее эффективный способ - использование префикса 0o (или 0O) для записи восьмеричных литералов.

# Восьмеричный литерал
num = 0o17  # 15 в десятичной
print(num)  # 15

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

15

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

Для преобразования десятичного числа в строку восьмеричного представления применяется функция oct() или строковое форматирование. Для обратного преобразования - int('строка', 8).

# Десятичное -> восьмеричное
dec_val = 42
print(oct(dec_val))        # '0o52'
print(f"{dec_val:o}")     # '52'
print(format(dec_val, 'o'))# '52'

# Восьмеричная строка -> десятичное
s = '52'
print(int(s, 8))          # 42

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

0o52
52
52
42

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

Этот подход покрывает 99% задач, связанных с восьмеричной системой.

Как преобразовать десятичное число в восьмеричное с префиксом?

Когда необходимо получить строку вида '0o...' (например, для вывода в консоль или записи в файл), используется oct().

num = 100
result = oct(num)
print(result)  # '0o144'

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

0o144

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

Возможная проблема: вызов oct() для числа с плавающей точкой приведёт к ошибке TypeError: 'float' object cannot be interpreted as an integer. Решение: предварительно преобразовать число к целому (int()).

# Ошибка
# oct(3.14)  # TypeError
# Исправление
oct(int(3.14))  # '0o3'

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

0o3

Как получить восьмеричное представление без префикса?

Для форматированного вывода без префикса 0o применяются format() или f-строка.

val = 255
print(format(val, 'o'))   # '377'
print(f"{val:o}")        # '377'

# Дополнение нулями до заданной ширины
print(f"{val:06o}")      # '000377'
377
377
000377

Возможная проблема: если использовать oct() и потом удалять префикс срезом (oct(255)[2:]), это менее читаемо и может сломаться при отрицательных числах. Решение: использовать format().

# Ненадёжный способ
print(oct(255)[2:])  # '377'
# Для отрицательных чисел
print(oct(-255)[3:]) # '377' (без знака) – неочевидно

# Надёжный способ
print(format(-255, 'o'))  # '-377'
377
377
-377

Как преобразовать строку с восьмеричным числом (с префиксом или без) в целое?

Для строки '0o52' или '52' подходит int() с указанием основания 8.

print(int('0o52', 8))  # 42
print(int('52', 8))    # 42
print(int('0O52', 8))  # 42  (допустим заглавный O)
42
42
42

Возможная проблема: если в строке присутствуют недопустимые символы (например, '8' или '9'), возникает ValueError: invalid literal for int() with base 8: '58'. Решение: предварительно проверять строку или обернуть вызов в try-except.

def safe_oct_to_int(s):
    try:
        return int(s, 8)
    except ValueError as e:
        print(f"Ошибка: {e}")
        return None

print(safe_oct_to_int('77'))   # 63
print(safe_oct_to_int('88'))   # Ошибка: invalid literal..., None
63
Ошибка: invalid literal for int() with base 8: '88'
None

Как выполнять арифметические операции и выводить результат в восьмеричном виде?

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

a = 0o10   # 8
b = 0o12   # 10
sum_dec = a + b
print(f"0o{a:o} + 0o{b:o} = 0o{sum_dec:o}  (в десятичной: {sum_dec})")

# Умножение
prod = a * b
print(f"0o{a:o} * 0o{b:o} = 0o{prod:o}")
0o10 + 0o12 = 0o22  (в десятичной: 18)
0o10 * 0o12 = 0o120

Возможная проблема: забыть, что литерал с префиксом - это обычное целое, и попытаться напрямую написать 0o10 + 0o12 (это корректно). А вот если пытаться склеивать строки без преобразования - результат будет неверным. Решение: всегда выполнять операции с числами, а форматирование применять только для вывода.

Как преобразовать большие числа или числа в других системах в восьмеричные?

Для шестнадцатеричных или двоичных строк сначала преобразуем в int, затем форматируем.

hex_str = 'FF'
dec = int(hex_str, 16)
oct_str = format(dec, 'o')
print(f"0x{hex_str} = 0o{oct_str}")

# Двоичная строка
bin_str = '1101'
dec2 = int(bin_str, 2)
print(f"0b{bin_str} = 0o{format(dec2, 'o')}")
0xFF = 0o377
0b1101 = 0o15

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

При чтении строки из файла её нужно преобразовать через int() с основанием 8, не забыв обработать возможные ошибки.

# Пример: файл содержит строки вида '755' (восьмеричное число)
# Имитация файла
lines = ['755', '644', '1a3']
for line in lines:
    try:
        val = int(line.strip(), 8)
        print(f"{line} -> {val}")
    except ValueError:
        print(f"Строка '{line}' не является восьмеричным числом")
755 -> 493
644 -> 420
Строка '1a3' не является восьмеричным числом

Расширенные примеры работы с восьмеричными числами

В этом разделе представлены нестандартные сценарии использования восьмеричной системы в Python.

Пример 1. Побитовые операции с выводом в восьмеричной системе

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

Пример
a = 0o70   # 56 в десятичной (двоичный 111000)
b = 0o33   # 27 (двоичный 011011)

print(f"a     = 0o{a:o}  {a:08b}")
print(f"b     = 0o{b:o}  {b:08b}")
print(f"a & b = 0o{a & b:o}  {(a & b):08b}")
print(f"a | b = 0o{a | b:o}  {(a | b):08b}")
print(f"a ^ b = 0o{a ^ b:o}  {(a ^ b):08b}")
print(f"~a    = 0o{(~a) & 0xFF:o}  {((~a) & 0xFF):08b}")  # маскируем до 8 бит
a     = 0o70  00111000
b     = 0o33  00011011
a & b = 0o20  00011000
a | b = 0o73  00111011
a ^ b = 0o53  00100011
~a    = 0o307  11000111

Пример 2. Генерация всех трёхзначных восьмеричных чисел и вывод их десятичных эквивалентов

Пример
print("Восьмеричное -> Десятичное")
for i in range(0o100, 0o1000):  # от 64 до 511
    print(f"0o{i:03o} -> {i}")
# Выведем только первые пять для краткости
Восьмеричное -> Десятичное
0o100 -> 64
0o101 -> 65
0o102 -> 66
0o103 -> 67
0o104 -> 68
...

Пример 3. Сортировка списка восьмеричных чисел, заданных в виде строк

Пример
oct_strings = ['0o10', '0o2', '0o77', '0o0', '0o100']
# Преобразуем в числа, сортируем, выводим обратно
nums = [int(s, 8) for s in oct_strings]
nums.sort()
sorted_oct = [f"0o{format(n, 'o')}" for n in nums]
print("Отсортированные восьмеричные:", sorted_oct)
Отсортированные восьмеричные: ['0o0', '0o2', '0o10', '0o77', '0o100']

Пример 4. Преобразование прав доступа Unix (символьный вид -> восьмеричный)

Пример
def perm_to_octal(perm_str: str) -> str:
    """Преобразует строку вида 'rwxr-xr-x' в восьмеричное число."""
    perm_map = {'r': 4, 'w': 2, 'x': 1, '-': 0}
    octal = 0
    for i, ch in enumerate(perm_str):
        if ch in perm_map:
            # Каждая группа по 3 символа
            shift = 2 - (i % 3)  # 2,1,0
            octal += perm_map[ch] << (shift * 3)  # сдвиг для каждой группы
    return oct(octal)

print(perm_to_octal('rwxr-xr-x'))  # 0o755
print(perm_to_octal('rw-------'))  # 0o600
0o755
0o600

Пример 5. Использование восьмеричных чисел при работе с сетевыми масками (IP)

Пример
# Допустим, маска подсети 0xFFFFFF00 (255.255.255.0) в восьмеричном виде
mask_hex = 0xFFFFFF00
print(f"Шестнадцатеричная: {hex(mask_hex)}")
print(f"Восьмеричная:     0o{format(mask_hex, 'o')}")
# Побитовое И с IP в восьмеричном представлении
ip = 0o10_0_0_1   # 0o10.0.0.1 = 0o10000001 (для примера)
network = ip & mask_hex
print(f"Сеть (восьмерично): 0o{format(network, 'o')}")
Шестнадцатеричная: 0xffffff00
Восьмеричная:     0o37777777400
Сеть (восьмерично): 0o0

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

Пример
def to_octal(n: int) -> str:
    if n == 0:
        return '0'
    elif n < 8:
        return str(n)
    else:
        return to_octal(n // 8) + str(n % 8)

print(to_octal(42))     # '52'
print(to_octal(255))    # '377'
print(to_octal(1000))   # '1750'
52
377
1750

Пример 7. Проверка корректности восьмеричной строки с помощью регулярного выражения

Пример
import re
pattern = r'^0[oO]?[0-7]+$'  # допускает '0o' или '0' или без префикса

def validate_oct(s):
    return bool(re.match(pattern, s))

tests = ['0o52', '0O77', '123', '0o18', '0o', '89']
for t in tests:
    print(f"'{t}': {validate_oct(t)}")
'0o52': True
'0O77': True
'123': True
'0o18': False
'0o': False
'89': False

Пример 8. Оптимизация: кэширование часто используемых восьмеричных чисел

Пример
from functools import lru_cache

@lru_cache(maxsize=128)
def to_oct_cached(n: int) -> str:
    return oct(n)

# При многократном вызове с одинаковыми аргументами кэш ускоряет работу
for i in range(100_000):
    _ = to_oct_cached(i % 256)  # только 256 уникальных значений

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

Восьмеричная система счисления в Python - comments

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