PythonPython 5. Системы счисления0%
Python для ЕГЭ · тема 5 из 11

Системы счисления

Перевод чисел между системами в одну строку, свой перевод в любую систему и IP-адреса с масками. После этой темы №14 решается кодом за пару минут.

7 разделов~40 минут№5, 10, 14
  1. 1bin, oct, hex
  2. 2int: из любой системы в десятичную
  3. 3Свой перевод в любую систему
  4. 4Неизвестная цифра x
  5. 5IP-адреса и маски
  6. 6Сломай код
  7. 7Где пригодится на ЕГЭ
Раздел 1 из 7

bin, oct, hex

Для трёх систем в Python есть готовые функции. Они выдают запись числа строкой, и в начале строки стоит приставка, которая показывает систему:

python
n = 2026
print(bin(n))    # двоичная
print(oct(n))    # восьмеричная
print(hex(n))    # шестнадцатеричная

Приставки 0b, 0o, 0x нам почти никогда не нужны. Отрезаем их срезом из прошлой темы:

python
n = 2026
b = bin(n)[2:]
print(b)
print('Единиц:', b.count('1'))
print('Цифр:', len(b))

Запомни связку bin(n)[2:]. Она нужна в №5 почти в каждой задаче.

Буквы-цифры

hex пишет буквы маленькими: 7ea. Если в проверке ищешь цифру A, пиши 'a' или переведи запись в большие буквы через .upper().

Раздел 2 из 7

int: из любой системы в десятичную

int умеет не только превращать строку в число. Если вторым аргументом указать основание, он прочитает запись в этой системе:

python
print(int('11111101010', 2))
print(int('7EA', 16))
print(int('2210001', 3))
print(int('Z', 36))      # основание до 36: цифры 0–9 и буквы A–Z

Это работает для любого основания от 2 до 36, большими или маленькими буквами, неважно. Обратно в произвольную систему готовой функции нет, её напишем сами в следующем разделе.

Попробуй самучебная задача

Сколько единиц в двоичной записи числа 2100 + 250 − 1?

Раздел 3 из 7

Свой перевод в любую систему

Помнишь из темы 3, как разбирать число на цифры через % 10 и // 10? Для любой системы всё то же самое, только вместо 10 основание k. Остаток это очередная цифра, только идут они с конца, поэтому приписываем каждую слева.

python
n = 2026
k = 7
digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
s = ''
while n > 0:
    s = digits[n % k] + s    # очередную цифру ставим СЛЕВА
    n //= k
print(s)

Зачем строка digits? Для систем больше 10 остаток может быть, например, 12, а цифра должна быть буквой C. digits[12] как раз и есть 'C'.

Проверим себя обратным переводом:

python
print(int('5623', 7))

Получили 2026, значит, перевод верный. Это хорошая привычка: перевёл в систему, переведи обратно через int.

Пример как в №14

Сколько цифр 2 в троичной записи числа 9100 + 350 − 2?

python
n = 9 ** 100 + 3 ** 50 - 2
s = ''
while n > 0:
    s = str(n % 3) + s     # для k ≤ 10 хватит str
    n //= 3
print(s.count('2'))

Python считает такие огромные числа точно, поэтому на ЕГЭ это решается за минуту.

Раздел 4 из 7

Неизвестная цифра x

Второй тип задач №14: в записи числа одна цифра неизвестна и обозначена x. Нужно найти x, при котором выполнено условие. Решение: перебираем все возможные цифры, подставляем в строку и читаем её через int.

Пример. В записи 1x2₉ + x13₉ цифра x одна и та же. При каком x сумма делится на 11?

python
digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
for x in range(9):                     # в девятеричной цифры от 0 до 8
    c = digits[x]
    a = int('1' + c + '2', 9)          # склеили запись и прочитали
    b = int(c + '13', 9)
    if (a + b) % 11 == 0:
        print(x, a + b)

Ответ x = 2. Цифра x меньше основания, поэтому range(9), а не range(10).

Ловушка: основание

Если x стоит в двух числах с разными основаниями, перебирать можно только цифры, допустимые в обоих. Для 9-ричной и 7-ричной это range(7). Иначе int выдаст ошибку invalid literal.

Попробуй самучебная задача

Сколько цифр 2 в троичной записи числа 9100 + 350 − 2? Запусти пример из раздела 3.

Раздел 5 из 7

IP-адреса и маски

IP-адрес это четыре числа от 0 до 255 через точку, например 192.168.1.10. Каждое число это 8 двоичных разрядов, всего 32. Маска выглядит так же, 255.255.255.224, и в двоичной записи это сначала единицы, потом нули. Единицы маски отмечают часть адреса, общую для всей сети.

Считать это руками долго, а в Python есть модуль ipaddress:

python
from ipaddress import ip_network

net = ip_network('192.168.1.0/255.255.255.224')
print(net.num_addresses)      # сколько адресов в сети
print(net.network_address)    # адрес сети
print(net.netmask)            # маска

Перебрать все адреса сети можно обычным циклом. Чтобы посмотреть на адрес в двоичной записи, превращаем его в число через int:

python
from ipaddress import ip_network

net = ip_network('10.8.0.0/255.255.248.0')
k = 0
for ip in net:
    if bin(int(ip)).count('1') <= 4:   # не больше 4 единиц в записи адреса
        k += 1
print(k)

Если дан адрес узла и маска, а сеть нужно найти, пишут strict=False:

python
from ipaddress import ip_network

net = ip_network('172.16.170.33/255.255.248.0', strict=False)
print(net.network_address)

strict=False разрешает дать адрес узла, а не сети. Без этого Python выдаст ошибку, что у адреса установлены биты справа от маски.

Попробуй самучебная задача

Найди цифру x, при которой 1x2₉ + x13₉ делится на 11.

Попробуй самучебная задача

Сколько адресов в сети с маской 255.255.255.224?

Раздел 6 из 7

Сломай код

ValueError: такой цифры нет

python
print(int('19', 8))

invalid literal for int() with base 8: в восьмеричной системе нет цифры 9. Если такое случилось при переборе x, проверь границу range.

Тихая ошибка: забыли отрезать 0b

python
n = 5
print(len(bin(n)))       # хотели узнать число разрядов
print(bin(n).count('0'))

Вышло 5 разрядов и 2 нуля, а у числа 5 в двоичной записи 101 три разряда и один ноль. Лишние символы дала приставка 0b. Нужно bin(n)[2:].

Тихая ошибка: цифры в обратном порядке

python
n = 6
s = ''
while n > 0:
    s = s + str(n % 2)    # приписали справа
    n //= 2
print(s)

Вышло 011, а 6 в двоичной это 110. Остатки идут с последней цифры, поэтому их приписывают слева: s = str(n % 2) + s.

Тихая ошибка: hex и большие буквы

python
print(hex(255)[2:].count('F'))

Вышло 0, хотя в записи ff две F. hex пишет буквы маленькими. Нужно .count('f') или .upper().count('F').

Раздел 7 из 7

Где пригодится на ЕГЭ

НомерЧто из темы
№5bin(n)[2:], работа с записью как со строкой, int(s, 2) обратно
№14свой перевод в любую систему, перебор неизвестной цифры x
№10IP-адреса и маски через ipaddress (с 2027 года маски в №10)

Задача про адреса из раздела 5, «сколько адресов сети с условием на двоичную запись», это типичный вопрос про маски. Попробуй сам:

Попробуй самучебная задача

Сколько адресов в сети 10.8.0.0 с маской 255.255.248.0 содержат в двоичной записи не больше 4 единиц?

Код в блоках можно менять и запускать прямо в браузере.