Перевод десятичного числа в любую систему счисления

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

Решение задачи на языке программирования Python

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

Например, перевод десятичных чисел 160 в восьмеричную и 18 в двоичную системы счисления будет выглядеть так:

160 / 8 = 20 | 0
 20 / 8 =  2 | 4
  2 / 8 =  0 | 2


16010 = 2408
18 / 2 = 9 | 0
 9 / 2 = 4 | 1
 4 / 2 = 2 | 0
 2 / 2 = 1 | 0
 1 / 2 = 0 | 1
1810 = 100102

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

150 // 10 = 15 | 0
 15 // 10 =  1 | 5
  1 // 10 =  0 | 1
15010 = 15010

Проблема появляется в тот момент, когда основание системы счисления начинает превышать 10. В таких случаях нам не хватает привычных символов цифр (0-9) и требуется ввод дополнительных символов для обозначения значений, соответствующих десятичным числам 10, 11, 12 и т. д. Для примера переведем десятичное число в шестнадцатеричную систему счисления:

700 // 16 = 43 | 12 (C)
 43 // 16 =  2 | 11 (B)
  2 // 16 =  0 | 2
70010 = 2BC16

Десятичные остатки 12 и 11 при формировании шестнадцатеричного числа должны быть представлены одним разрядом. В таких случаях в качестве цифр, чье значение больше 9-ти, используются английские буквы. Так числу 10 будет соответствовать символ A, числу 11 - B и т. д.

Таким образом, при написании программы перевода десятичного числа в любую систему счисления мы должны предусмотреть подмену остатков на соответствующие им символы, если эта замена требуется.

Будем усложнять программу поэтапно и сначала напишем вариант кода, который переводит не в любую систему счисления, а только с основанием до 10-ти.

num = int(input())
base = 0
while not (2 <= base <= 9):
    base = int(input('Основание (2-9): '))

new = ''

while num > 0:
    remainder = num % base
    new = str(remainder) + new
    num = num // base

print(new)

В цикле сначала вычисляется остаток. Далее присоединяем его спереди к строковой переменной new, в которой хранится представление числа в новой системе счисления. Последним действием присваиваем переменной num частное от целочисленного деления прежнего значения num на основание системы счисления.

Поскольку в языке программирования Python есть функция divmod, сократим код, объединив нахождение остатка и целочисленное деление:

...
while num > 0:
    num, remainder = divmod(num, base)
    new = str(remainder) + new
...

Вызов divmod(num, base) возвращает кортеж из частного и остатка от деления num на base. Далее частное присваивается num, остаток - remainder.

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

num = int(input())
base = 16
letters = 'ABCDEF'
new = ''

while num > 0:
    num, remainder = divmod(num, base)
    if remainder > 9:
        letter_id = remainder - 10
        remainder = letters[letter_id]
    new = str(remainder) + new

print(new)

Числу 10 соответствует символ A. Поэтому если остаток равен десяти, то letter_id будет равно нулю. Символ под индексом 0 в строке букв - как раз A. Если остаток равен 15-ти, то letter_id будет равно пяти, а letters[5] вернет F.

Программу можно упростить, если в строку символов добавить цифры. В этом случае остатки будут точно соответствовать индексам, под которыми находятся соответствующие им символы.

num = int(input())
base = 16
letters = '0123456789ABCDEF'
new = ''

while num > 0:
    num, remainder = divmod(num, base)
    new = letters[remainder] + new

print(new)

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

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

num = int(input())
base = 0
while not (2 <= base <= 36):
    base = int(input('Основание (2-36): '))

new = ''

while num > 0:
    num, remainder = divmod(num, base)
    if remainder > 9:
        letter = remainder - 10
        remainder = chr(ord('A') + letter)
    new = str(remainder) + new

print(new)

Вызов ord('A') возвращает код буквы A в таблице Unicode. К этому коду-числу мы прибавляем смещение по алфавиту (значение letter). С помощью функции chr() получаем соответствующую коду букву.

В виде функции:

def convert_integer(decimal, radix):
    if radix > 36:
        return 'Основание системы счисления должно быть не больше 36-ти'

    number = ''
    while decimal > 0:
        decimal, remainder = divmod(decimal, radix)
        if remainder > 9:
            remainder = chr(ord('A') + remainder - 10)
        number = str(remainder) + number
    return number


num = int(input('Десятичное число: '))
base = int(input('Основание (2-36): '))
print(convert_integer(num, base))

Ограничение по основанию в 36 связано с количеством букв в английском алфавите. Их 26, плюс десять цифр. Расширить диапазон оснований можно за счет взятия недостающих символов из какой-либо другой части таблицы Unicode. Например, можно добавить к условному оператору ветку elif с условием remainder > 35, а в теле вычитать из remainder 36.

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

Больше задач в PDF


Решение задач на Python




Все разделы сайта