okpython.net
Все для начинающих

Перевод чисел из одной системы счисления в другую

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

Калькулятор перевода чисел между СС

Инструкция калькулятора

 Назначение 

Калькулятор (конвертер) служит для перевода неотрицательных целых и дробных действительных чисел длиной не более 200 символов из одной системы счисления в другую.

Поддерживаются системы счисления с основаниями от 2 до 36.

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

 Перевод целых чисел 

Перевести целое число 2547 из 10-й системы счисления в 16-ю.

Заполняем поля:
Исходная СС - 10
Переводим число - 2547
В систему счисления - 16

Жмем кнопку «Перевести», получаем результат: 9F3.
Чтобы скопировать результат в буфер обмена, жмем кнопку «Копировать».

 Перевод дробных чисел 

Перевести дробное число 25.753 из 8-й системы счисления в 16-ю.

Заполняем поля:
Исходная СС - 8
Переводим число - 25.753
В систему счисления - 16

Жмем кнопку «Перевести», получаем результат: 15.F58.
Чтобы скопировать результат в буфер обмена, жмем кнопку «Копировать».

Вступление к теории

В повседневной жизни мы привыкли иметь дело с десятичной системой счисления, в которой числа образуются при помощи цифр 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Однако современные компьютеры на аппаратном уровне работают только с цифровыми данными представленными в двоичной системе счисления, в которой числа образуются при помощи двух цифр 0 и 1. Это связано с тем, что компьютеры для обработки информации используют устройства, которые могут принимать только два различных устойчивых состояния, например, заряжен или не заряжен, намагничен или не намагничен, есть ток или нет тока и т.д. Одно из состояний устройства принимается за ноль, а другое – за единицу. После объединения множества таких простейших устройств в одно сложное, например, процессор, как раз и появляется возможность обрабатывать данные в виде чисел в двоичной системе счисления. Но поскольку двоичные числа очень длинные, то для более короткой и удобной их записи при составлении программ на языке машинных кодов используются промежуточные восьмеричная и шестнадцатеричная системы счисления, числа в которых образуются, соответственно, при помощи цифр 0, 1, 2, 3, 4, 5, 6, 7 и 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. Все это приводит к тому, что в ходе написания программ время от времени появляется необходимость перевода чисел из одной системы счисления в другую. Рассмотрением данного вопроса мы как раз и займемся в данной статье.

Перевод целых чисел и правильных дробей из десятичной системы
счисления в систему счисления с основанием «n»

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

1. Для перевода целых чисел из десятичной системы счисления в систему счисления с основанием «n» используется следующий алгоритм.

  • Исходное десятичное число a делится нацело на основание n, в результате чего получается частное c_1 и остаток от деления r_1, который фиксируется.
  • Далее, частное c_1 вновь делится на основание n, остаток r_2 фиксируется, а вся процедура повторяется заново до тех пор, пока частное не станет равным нулю (частное, а не остаток!).
  • В самом конце из полученных остатков, записанных в порядке, обратном их получению, составляется требуемое число в новой системе счисления с основанием «n».

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

   35:2 = 17 (остаток 1) //фиксируем 1
   17:2 = 8  (остаток 1) //фиксируем 1
   8:2 = 4   (остаток 0) //фиксируем 0
   4:2 = 2   (остаток 0) //фиксируем 0
   2:2 = 1   (остаток 0) //фиксируем 0
   1:2 = 0   (остаток 1) //фиксируем 1
   --------------------------------
   Результат: 3510 = 1000112.

   35:8 = 4 (остаток 3) //фиксируем 3
   4:8 = 0  (остаток 4) //фиксируем 4
   --------------------------------
   Результат: 3510 = 438.

   35:16 = 2 (остаток 3) //фиксируем 3
   2:16 = 0  (остаток 2) //фиксируем 2
   --------------------------------
   Результат: 3510 = 2316.

2. Для перевода правильных дробей из десятичной системы счисления в систему счисления с основанием «n» алгоритм имеет другой вид.

  • Исходное десятичное число a, модуль которого меньше единицы (|a|<1), умножается на основание n, после чего целая часть результата произведения фиксируется.
  • Далее, дробная часть результата вновь умножается на основание n, целая часть нового результата фиксируется, а вся процедура повторяется заново до тех пор, пока дробная часть очередного результата не станет равной нулю либо не будет достигнута требуемая точность числа в новой системе счисления с основанием n.
  • В самом конце составляется требуемое число в новой системе счисления. Для этого записывается нулевая целая часть числа, а затем из зафиксированных ранее целых частей, при чем в той последовательности, в которой они были получены, составляется его дробная часть.

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

Вес P младшего разряда числа в текущей системе счисления, т.е. точность, которую обеспечивает данный разряд, определяется по формуле P = 1/(nk), где n - основание системы счисления, k - количество разрядов после запятой. Следовательно, для двух систем счисления равенство весов будет иметь вид: 1/(n_1k_1) = 1/(n_2k_2), откуда требуемое минимальное количество разрядов числа после перевода будет равно k_2 = k_1/(logn_1n_2). Например, вес младшего разряда числа 0.6 в десятичной системе счисления будет равен 1/(101) = 0.1. Поэтому в случае перевода его, например, в двоичную систему счисления с точностью до сотых в исходной системе, количество разрядов конечного числа должно быть не менее 7, т.к. 2/(log102) ≈ 2/0.3 ≈ 6.6. Таким образом при обратном переводе мы получим исходное число с точностью до одной сотой.

Заметим, что если при переводе числа из десятичной в требуемую систему счисления, получается бесконечная дробь (периодическая или непериодическая), то в общем случае нам придется мириться с потерей точности числа, отсекая лишние разряды. Следовательно, целевое число будем меньше исходного.

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

   Требуемое количество разрядов k2 = 7, т.к. 2/log102 ≈ 6.6.
   0.3*2 = 0.6 (целая часть рез-та равна 0) //фиксируем 0
   0.6*2 = 1.2 (целая часть рез-та равна 1) //фиксируем 1
   0.2*2 = 0.4 (целая часть рез-та равна 0) //фиксируем 0
   0.4*2 = 0.8 (целая часть рез-та равна 0) //фиксируем 0
   0.8*2 = 1.6 (целая часть рез-та равна 1) //фиксируем 1
   0.6*2 = 1.2 (целая часть рез-та равна 1) //фиксируем 1
   0.2*2 = 0.4 (целая часть рез-та равна 0) //фиксируем 0
   --------------------------------
   Результат: 0.310 = 0.01001102.
   Обратный перевод: 0.01001102 = 0.29687510 (ε ≤ 0.01).

   Требуемое количество разрядов k8 = 3, т.к. 2/log108 ≈ 2.2. 
   0.3*8 = 2.4 (целая часть рез-та равна 2) //фиксируем 2
   0.4*8 = 3.2 (целая часть рез-та равна 3) //фиксируем 3
   0.2*8 = 1.6 (целая часть рез-та равна 1) //фиксируем 1
   --------------------------------
   Результат: 0.310 = 0.2318.
   Обратный перевод: 0.2318 = 0.29882812510 (ε ≤ 0.01).

   Требуемое количество разрядов k16 = 2, т.к. 2/log1016 ≈ 1.66. 
   0.3*16 = 4.8  (целая часть рез-та равна 4) //фиксируем 4
   0.8*16 = 12.8 (целая часть рез-та равна 1210 = C16) //фиксируем C
   --------------------------------
   Результат: 0.310 = 0.4C16.
   Обратный перевод: 0.4C16 = 0.29687510 (ε ≤ 0.01).

3. В общем случае для перевода вещественных чисел из десятичной системы счисления в систему счисления с основанием «n» следует отдельно перевести его целую и дробную части, а затем дописать дробную часть к целой. Например, для числа 35.310 получим:

   35.310 = 1000112 + 0.01001102 = 100011.01001102;
   35.310 = 438 + 0.2318 = 43.2318;
   35.310 = 2316 + 0.4C16 = 23.4C16.

4. Из всего выше сказанного следует, что перевод числа из системы счисления с основанием «n» в систему счисления с основанием «m» можно осуществить в два этапа:

  • в начале переводим число в десятичную систему счисления;
  • а затем в нужную нам систему счисления с основанием «m».

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

Перевод чисел из системы счисления с основанием «n»
в десятичную систему счисления

Начнем с того, что в общем случае число c в позиционной системе счисления может быть разложено по степеням своего основания «n» и представлено в виде полинома в десятичной системе счисления:
c = ma-1*na-1 + ma-2*na-2 + ... + m1*n1 + m0*n0 + m-1*n-1 + ... + m-b*n-b , где
n – основание исходной системы счисления;
a – количество разрядов целой части в исходном числе;
b – количество разрядов дробной части в исходном числе;
mi – значение цифры в i-ом разряде исходного числа, где i изменяется от a-1 до -b.

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

В качестве примеров переведем числа наших примеров обратно в десятичную систему счисления.

   100011.01001102 = 1*25 + 0*24 + 0*23 + 0*22 + 1*21 + 
   + 1*20 + 0*2-1 + 1*2-2 + 0*2-3 + 0*2-4 + 
   + 0*2-5 + 0*2-6 + 0*2-7 = 35.29687510;	

   43.2318 = 4*81 + 3*80 + 2*8-1 + 3*8-2 + 3*8-3 = 35.29882812510;

   23.4C16 = 2*161 + 3*160 + 4*16-1 + 4*16-2 = 35.29687510.

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

Перевод чисел из системы счисления с основанием 2n
в систему счисления с основанием 2m и обратно

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

1. В общем случае перевод чисел из двоичной системы счисления в систему счисления с основанием 2n довольно прост и осуществляется по следующему общему алгоритму:

  • разряды исходного двоичного числа группируются по n разрядов влево и вправо от точки, разделяющей целую и дробную части;
  • далее, неполные группы двоичных цифр по краям исходного числа дополняются незначащими нулями;
  • после чего каждую из полученных групп двоичных цифр заменяют соответствующей ей цифрой системы счисления с основанием 2n.

Отметим, что для восьмеричной системы счисления разряды разбиваются на тройки, которые называют двоичными триадами, а для шестнадцатеричной – на четверки, которые называют двоичными тетрадами. Триады и тетрады вместе с соответствующими им цифрами в восьмеричной и шестнадцатеричной системах счисления представлены в следующей таблице:

Триада Число N8 Тетрада Число N16
000 0 0000 0
001 1 0001 1
010 2 0010 2
011 3 0011 3
100 4 0100 4
101 5 0101 5
110 6 0110 6
111 7 0111 7
1000 8
1001 9
1010 A
1011 B
1100 C
1101 D
1110 E
1111 F

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

   10110010011.11010101100011 -> 
    -> 010 110 010 011.110 101 011 001 100 -> 2623.653068; 
10110010011.11010101100011 -> -> 0101 1001 0011.1101 0101 1001 1000 -> 593.D58C16.

2. Для перевода чисел из восьмеричной и шестнадцатеричной систем счисления в двоичную нужно:

  • заменить каждую цифру числа соответствующей двоичной триадой или тетрадой (воспользовавшись таблицей выше);
  • и далее, опустить незначащие нули в старших разрядах целой части и младших разрядах дробной части.

В качестве примера осуществим обратный перевод чисел предыдущего примера в двоичную систему:

   2623.653068 -> 010 110 010 011.110 101 011 001 -> 
   010010110010011.11010101100011 -> 10010110010011.11010101100011;

   593.D58C16 -> 0101 1001 0011.1101 0101 1001 1000 -> 
   010110010011.1101010110011000 -> 10110010011.11010101100011.

В конце добавим, что перевод чисел из восьмеричной системы счисления в шестнадцатеричную или обратно, можно осуществить в два этапа:

  • в начале переводим число в двоичную систему счисления;
  • а затем в нужную нам восьмеричную или шестнадцатеричную систему счисления.

Задачи на закрепление теории

1. Переведите число 1937 из 10-й системы счисления в двоичную. Показать решение.

Решение pythonCodes
	
   Для перевода целого числа из 10-ной системы в двоичную (или 
   другую) систему счисления необходимо делить это число, фиксируя 
   остатки от деления, на основание новой системы (в нашем случае 
   это 2) до тех пор, пока частное не станет равным нулю. 

   1937:2 = 968 (остаток 1) //фиксируем 1
   968:2 = 484  (остаток 0) //фиксируем 0
   484:2 = 242  (остаток 0) //фиксируем 0
   242:2 = 121  (остаток 0) //фиксируем 0
   121:2 = 60   (остаток 1) //фиксируем 1
   60:2 = 30    (остаток 0) //фиксируем 0
   30:2 = 15    (остаток 0) //фиксируем 0
   15:2 = 7     (остаток 1) //фиксируем 1
   7:2 = 3      (остаток 1) //фиксируем 1
   3:2 = 1      (остаток 1) //фиксируем 1
   1:2 = 0      (остаток 1) //фиксируем 1

   Результат: 193710 = 111100100012.

   Помним, что результат составляется из последовательности 
   остатков, начиная с последнего!

Решение задачи №1

2. Переведите число 207 из 8-й системы счисления в 10-ную. Показать решение.

Решение pythonCodes
		
   Вспоминаем, что в общем случае для перевода числа из системы 
   счисления с основанием «n» в десятичную систему счисления нужно 
   представить его в виде соответствующего полинома, а затем просто 
   вычислить получившуюся сумму:
   2078 = 2*82 + 0*81 + 7*80 = 128 + 0 + 7 = 13510 
   Результат: 2078 = 13510.

Решение задачи №2

3. Как известно, цветовая модель RGB (от англ. Red, Green, Blue) для получения цвета любого оттенка использует три десятичных числа от 0 до 255 или же три соответствующих шестнадцатеричных числа, которые описывают относительное содержание красного, зеленого и синего цветов. Так в HTML в случае десятичного представления формат записи значения цвета имеет вид rgb(r,g,b). Если же используется шестнадцатеричное представление чисел, в котором разрешается использовать цифры от 0 до 9 и латинские буквы в любом регистре от A до F, то значение цвета записывают в формате #rrggbb. Например, правила p{color: rgb(165,42,42);} и p{color: #a52a2a;} задают для абзаца одно и тоже значение коричневого цвета, соответствующее названию цвета brown.

а. Переведите значение цвета rgb(55,73,199) из 10-го формата в 16-ый.

b. Переведите 16-ое значение цвета #FA453D в 10-ый формат. Показать решение.

Решение pythonCodes
			
   Решение пункта a задачи.

   Переведем 10-ное значение красного цвета в 16-ное:
   55:16 = 3 (остаток 7) //фиксируем 7
   3:16 = 0  (остаток 3) //фиксируем 3
   Результат: 5510 = 3716.
	
   Переведем 10-ное значение зеленого цвета в 16-ное:
   73:16 = 4 (остаток 9) //фиксируем 9
   4:16 = 0  (остаток 4) //фиксируем 4
   Результат: 7310 = 4916.	
		
   Переведем 10-ное значение синего цвета в 16-ное:
   199:16 = 12 (остаток 7) //фиксируем 7
   12:16 = 0  (остаток 12) //фиксируем 1210 = C16
   Результат: 19910 = C716.

   Т.о. rgb(55,73,199) -> #3749C7.
	
   ------------------------

   Решение пункта b задачи.

   Переведем 16-ное значение красного цвета в 10-ное:
   FA16 = 15*161 + 10*160 = 240 + 15 = 25010 (F16 = 1510, A16 = 1010)

   Переведем 16-ное значение зеленого цвета в 10-ное:
   4516 = 4*161 + 5*160 = 64 + 5 = 6910 

   Переведем 16-ное значение синего цвета в 10-ное:
   3D16 = 3*161 + 13*160 = 48 + 13 = 6110 (D16 = 1310)

   Т.о. #FA453D -> rgb(250,69,61).

Решение задачи №3

4. Найдите значение выражения в десятичной системе счисления:
1E.A16 + 0101.11012 - 23.58 - 6.812510 Показать решение.

Решение pythonCodes
	
   Переводим числа в 10-ную систему счисления, 
   составляя полиномы и вычисляя их суммы:

   1E.A16 = 1*161 + 14*160 + 10*16-1 = 16 + 15 + 0.625 = 30.62510 
   Помним, что E16 = 1410, A16 = 1010.

   0101.11012 = 0*23 + 1*22 + 0*21 + 1*20 + 1*2-1 + 1*2-2 + 0*2-3 + 
   + 1*2-4 = 0 + 4 + 0 + 1 + 1/2 + 1/4 + 0 + 1/16 = 
   = 5+13/16 = 5.812510 

   23.58 = 2*81 + 3*80 + 5*8-1 = 16 + 3 + 5/8 = 19.62510

   Вычисляем: 30.625 + 5.8125 - 19.625 - 6.8125 = 10.
   Ответ: 10.	

Решение задачи №4

5. Переведите десятичное число 3.79 в двоичную систему с точностью до одной тысячной в исходной системе счисления. Показать решение.

Решение pythonCodes
	
   Переведем по отдельности целую и дробную части числа. 

   3:2 = 1 (остаток 1) //фиксируем 1
   1:2 = 0 (остаток 1) //фиксируем 1
   Результат: 310 = 112.	

   При переводе дробной части учтем, что нам требуется точность 
   0.00110 = 3) в 10-ной системе счисления. Поэтому количество 
   разрядов, которое нам потребуется сохранить в итоговом числе, 
   будет приблизительно равно: к2 = 3/(log102) ≈ 3/0.301 ≈ 9.96. 
   Т.е. в итоговом числе нам потребуются 10 цифр после запятой.   

   0.79*2 = 1.58 //фиксируем 1
   0.58*2 = 1.16 //фиксируем 1
   0.16*2 = 0.32 //фиксируем 0	
   0.32*2 = 0.64 //фиксируем 0	
   0.64*2 = 1.28 //фиксируем 1	
   0.28*2 = 0.56 //фиксируем 0	
   0.56*2 = 1.12 //фиксируем 1	
   0.12*2 = 0.24 //фиксируем 0	
   0.24*2 = 0.48 //фиксируем 0	
   0.48*2 = 0.96 //фиксируем 0	
   Результат: 0.7910 = 0.11001010002.

   Итог: 3.7910 = 112 + 0.11001010002 = 11.11001010002.

Решение задачи №5

6. Переведите число 0112 в троичную систему счисления. Показать решение.

Решение pythonCodes
	
   Чтобы перевести число из одной системы счисления в другую, 
   нужно сперва перевести его в десятичную систему счисления, 
   а уже потом в целевую. 

   1. 0112 = 0*22 + 1*21 + 1*20 = 0 + 2 + 1 = 310 

   2. 3:3 = 1 (остаток 0) //фиксируем 0
   1:3 = 0 (остаток 1) //фиксируем 1
   Результат: 310 = 103.	
	 
   Ответ: 0112 = 103.

Решение задачи №6

7. Переведите число 1748 в 16-ную систему счисления. Показать решение.

Решение pythonCodes
   
   Давайте вначале переведем число в двоичную, 
   а уже потом и в 16-ную систему счисления. 

   1. Заменим каждую цифру числа соответствующей триадой 
   (1 -> 001, 7 -> 111, 4 -> 100): 
   1748 = 0011111002 

   2. Разобьем полученное число на тетрады, дописав слева 
   недостающие нули:
   001111100 -> 0000 0111 1100.
   Используя таблицу тетрад, получаем цифры итогового числа:
   0000 -> 0, 0111 -> 7, 1100 -> C.
   Получаем: 0011111002 = 7C16

   Ответ: 1748 = 7C16. 

Решение задачи №7