Задание 2: системы счисления — перевод 2/8/10/16
Учимся свободно переводить числа между системами счисления — это задание №2.
Система счисления — способ записи чисел набором цифр; основание показывает, сколько цифр используется (2, 8, 10 или 16).
Что проверяет задание 2
В задании 2 дают число в одной системе и просят перевести в другую, либо сравнить числа, записанные в разных системах. Чаще всего фигурируют двоичная (основание 2), восьмеричная (8), десятичная (10) и шестнадцатеричная (16, цифры A–F для 10–15).
Перевод в десятичную: «развернуть по разрядам»
Любое число можно перевести в десятичную, умножив каждую цифру на основание в степени её позиции (справа налево, начиная с 0).
Пример: 10011100₂ → ? Считаем по разрядам: 1·128 + 0·64 + 0·32 + 1·16 + 1·8 + 1·4 + 0·2 + 0·1 = 156.
print("Из двоичной:", int("10011100", 2))
print("Из восьмеричной:", int("234", 8))
print("Из шестнадцатеричной:", int("9C", 16))
Вывод:
Из двоичной: 156 Из восьмеричной: 156 Из шестнадцатеричной: 156
Все три записи — это одно и то же число 156, просто в разных системах.
Перевод из десятичной: «деление с остатком»
Чтобы перевести десятичное число в систему с основанием b, делим его на b с остатком, пока не получим 0. Остатки, выписанные снизу вверх, дают результат.
Пример: 156 → в двоичную. 156÷2=78 (ост.0), 78÷2=39 (0), 39÷2=19 (1), 19÷2=9 (1), 9÷2=4 (1), 4÷2=2 (0), 2÷2=1 (0), 1÷2=0 (1). Снизу вверх: 10011100.
def to_base(num, base):
if num == 0:
return "0"
digits = "0123456789ABCDEF"
res = ""
while num > 0:
res = digits[num % base] + res
num //= base
return res
print("156 в 2:", to_base(156, 2))
print("156 в 8:", to_base(156, 8))
print("156 в 16:", to_base(156, 16))
Вывод:
156 в 2: 10011100 156 в 8: 234 156 в 16: 9C
Быстрые переходы 2 ↔ 8 ↔ 16
Между «родственными» системами можно переводить без десятичной, группируя двоичные цифры:
- 2 → 8: группируй биты по 3 справа, каждую тройку замени восьмеричной цифрой.
- 2 → 16: группируй биты по 4 справа, каждую четвёрку — шестнадцатеричной цифрой.
Например, 10011100₂ по 4 бита: 1001 1100 → 9 C → 9C₁₆. Так гораздо быстрее, чем гонять через десятичную.
| 16-рич. | 0 | 1 | 2 | ... | 9 | A | B | C | D | E | F |
| Десятич. | 0 | 1 | 2 | ... | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Перевод 2→8 устроен так же, но группами по 3 бита: 10011100₂ → справа по три → 10 011 100 → дополним левую группу нулями до 010 → 2 3 4 → 234₈. Сверим всё расчётом сразу для двух группировок:
b = "10011100"
# дополним слева нулями до кратности 3 и 4
b3 = b.zfill(((len(b) + 2) // 3) * 3)
b4 = b.zfill(((len(b) + 3) // 4) * 4)
print("по 3 бита:", [b3[i:i+3] for i in range(0, len(b3), 3)], "->", oct(int(b, 2))[2:])
print("по 4 бита:", [b4[i:i+4] for i in range(0, len(b4), 4)], "->", hex(int(b, 2))[2:].upper())
Вывод:
по 3 бита: ['010', '011', '100'] -> 234 по 4 бита: ['1001', '1100'] -> 9C
Видно, как группы битов один-в-один превращаются в восьмеричные и шестнадцатеричные цифры. Этот приём экономит время: вместо длинного деления вы просто разбиваете число на группы и переводите каждую отдельно.
Сравнение чисел из разных систем
Если просят сравнить, например, 27₈ и 1A₁₆, не сравнивайте их «как написано». Переведите оба в десятичную: 27₈ = 23, 1A₁₆ = 26. Значит 1A₁₆ больше.
a = int("27", 8)
b = int("1A", 16)
print(a, "<", b, "->", a < b)
Вывод:
23 < 26 -> True
Типичные ошибки
- Читают остатки сверху вниз (надо — снизу вверх).
- Забывают, что A=10, B=11, …, F=15 в шестнадцатеричной.
- Группируют биты слева, а не справа — теряют ведущие нули.
- Сравнивают числа «по виду», не приведя к одной системе.
Итог
- В десятичную — «развернуть по разрядам»; из десятичной — «деление с остатком, снизу вверх».
- 2↔8 — группами по 3 бита, 2↔16 — по 4 бита, справа.
- Для сравнения всё приводят к десятичной.
- В шестнадцатеричной A–F = 10–15.