Курс 3.8 — Алгоритмы · Раздел 03 · Урок 3.4

Сложение чисел в позиционной системе счисления

Разберём сложение по разрядам и перенос в следующий разряд.

Разберём сложение по разрядам и перенос в следующий разряд.
3.4 — Сложение чисел в позиционной системе счисления

Материал урока

С клавиатуры вводится целое положительное число p (1

Для решения задачи будем разбирать числа с конца, как и в предыдущих задачах. При сложении двух соответствующих разрядов мы получим значение разряда результата и перенос в следующий разряд. Если одно из чисел заканчивается раньше, это не проблема — можно считать, что у него нулевые разряды.

Пример кода для решения задачи:

p = int(input("Введите основание системы счисления p (2 ≤ p ≤ 10): "))
n = int(input("Введите первое число (в p-ичной системе, но записанное как обычное число): "))
m = int(input("Введите второе число (в p-ичной системе, но записанное как обычное число): "))

result = 0
carry = 0
weight = 1

while n > 0 or m > 0 or carry > 0:
    total = (n % 10) + (m % 10) + carry
    result += (total % p) * weight
    carry = total // p
    n //= 10
    m //= 10
    weight *= 10

print(result)

Разберём алгоритм:

  1. Сначала мы вводим все необходимые значения
  2. Организуем цикл с предусловием. Условие продолжения цикла — одновременное равенство 0 чисел n и m, а также значению переноса, которое хранится в переменной tran
  3. Переменная w отвечает за вес разряда, который мы формируем в этот момент. Поскольку мы моделируем число в десятичной системе, значение w будет увеличиваться в 10 раз на каждом шаге
  4. Внутри цикла мы считаем сумму sum младших разрядов чисел n и m и значения переноса tran
  5. Записываем остаток от деления sum на p в разряд результата, а целую часть — в новый перенос tran
  6. Отбрасываем младшие разряды чисел и увеличиваем вес. При этом какое-то из чисел может стать равным нулю. Это не страшно, просто далее оно никак не будет влиять на результат
  7. Переходим на следующую итерацию

У этого алгоритма тоже линейная сложность.

Пример кода с визуализацией шагов алгоритма

p = int(input("Введите основание системы счисления p (2 ≤ p ≤ 10): "))
n = int(input("Введите первое число (в p-ичной системе, но записанное как обычное число): "))
m = int(input("Введите второе число (в p-ичной системе, но записанное как обычное число): "))

if not (2 <= p <= 10):
    print("Основание должно быть от 2 до 10.")
else:
    print(f"\nСкладываем {n} и {m} в системе с основанием {p}.")

    result = 0       # Результат в decimal-формате записи цифр p-ичной системы
    carry = 0        # Перенос в следующий разряд (tran в C++)
    weight = 1       # Место для записи следующей цифры (1, 10, 100, ...)
    step = 1

    while n > 0 or m > 0 or carry > 0:
        digit_n = n % 10  # младшая цифра первого числа
        digit_m = m % 10  # младшая цифра второго числа

        total = digit_n + digit_m + carry  # сумма с переносом

        new_digit = total % p              # цифра для текущего разряда
        carry = total // p                 # перенос в следующий разряд

        print(f"\nШаг {step}:")
        print(f"  Цифра из первого числа: {digit_n}")
        print(f"  Цифра из второго числа: {digit_m}")
        print(f"  Перенос из прошлого шага: {carry if step == 1 else carry_before}")
        print(f"  Сумма: {digit_n} + {digit_m} + {carry if step == 1 else carry_before} = {total}")
        print(f"  Цифра в этом разряде (mod {p}): {new_digit}")
        print(f"  Новый перенос: {carry}")

        result += new_digit * weight
        weight *= 10

        # Сохраняем перенос до изменения, чтобы красиво вывести на следующем шаге
        carry_before = carry

        # Убираем уже сложенные цифры
        n //= 10
        m //= 10
        step += 1

    print(f"\n✅ Результат сложения в p-ичной системе (в виде decimal-записи цифр): {result}")