Урок 44. Перевод чисел из двоичной системы в десятичную и наоборот

   ⁄ 

 Обновлено 2 Мар 2017

  ⁄   

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

Рассмотрим нормальное десятичное число, например, 5623. Интуитивно понятно, что означают эти цифры: (5 * 1000) + (6 * 100) + (2 * 10) + (3 * 1). Так как в десятичной системе всего 10 цифр, то каждое значение умножается на множитель 10 в степени n. Выражение выше можно записать еще так: (5 * 103) + (6 * 102) + (2 * 101) + (3 * 1).

Двоичные числа работают по точно такой же схеме, за исключением того, что есть только 2 числа (0 и 1) и множитель не 10, а 2. Так же как запятые используются для улучшения читабельности больших десятичных чисел (например: 1, 427, 435), двоичные числа пишутся группами (в каждой по 4 цифры). Например: 1101 0101.

Напомним, в бинарной системе, от 0 до 15 отсчет ведется так:

Десятичное значение Двоичное значение
0 0
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111

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

В примерах ниже, предполагается, что мы имеем дело с целыми числами unsigned.

Рассмотрим 8 битовое (1 байтовое) двоичное число: 0101 1110. Оно означает (0 * 128) + (1 * 64) + (0 * 32) + (1 * 16) + (1 * 8) + (1 * 4 ) + (1 * 2) + (0 * 1). Если суммировать, то получим десятичное 64 + 16 + 8 + 4 + 2 = 94.

Вот тот же процесс только в таблице. Мы умножаем каждую двоичную цифру на её значение, которое определяется её положением. Переведем 0101 1110 в десятичную систему:

Двоичный символ 0 1 0 1 1 1 1 0
* Значение символа 128 64 32 16 8 4 2 1
= Результат (94) 0 64 0 16 8 4 2 0

Конвертируем 1001 0111 в десятичную систему:

Двоичный символ 1 0 0 1 0 1 1 1
* Значение символа 128 64 32 16 8 4 2 1
= Результат (151) 128 0 0 16 0 4 2 1

1001 0111 (бинарное) = 151 (десятичное).

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

Перевод чисел из десятичной системы в двоичную. Способ №1

Конвертирование из десятичной системы в бинарную чуть-чуть сложнее, но все же остается довольно простым занятием. Есть два способа.

Первый заключается в непрерывном делении числа на 2 и записывании остатков. Если остаток (r) есть, то пишем 1, если нет – 0. Затем, читая их снизу вверх, мы получим готовое бинарное число.

Конвертация 148 из десятичной системы в двоичную:

148 / 2 = 74 r0
74 / 2 = 37 r0
37 / 2 = 18 r1
18 / 2 = 9 r0
9 / 2 = 4 r1
4 / 2 = 2 r0
2 / 2 = 1 r0
1 / 2 = 0 r1

Записываем остатки снизу вверх: 1001 0100.

148 в десятичной системе = 1001 0100 в двоичной.

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

(1 * 128) + (0 * 64) + (0 * 32) + (1 * 16) + (0 * 8) + (1 * 4) + (0 * 2) + (0 * 1) = 148.

Перевод чисел из десятичной системы в двоичную. Способ №2

Этот способ хорошо подходит для небольших двоичных чисел. Рассмотрим 148 еще раз. Какое наибольшее число, умноженное на 2 (из ряда: 1, 2, 4, 8, 16, 32, 64, 128, 256 и т.д.), меньше 148? Ответ: 128.

148 >= 128? Да, поэтому 128 бит равен 1. 148 − 128 = 20
20 >= 64? Нет, поэтому 64 бит равен 0.
20 >= 32? Нет, 32 бит равен 0.

20 >= 16? Да, 16 бит равен 1. 20 − 16 = 4
4 >= 8? Нет, 8 бит равен 0.
4 >= 4? Да, 4 бит равен 1. 4 − 4 = 0, что означает, что все остальные биты равны 0.

148 = (1 * 128) + (0 * 64) + (0 * 32) + (1 * 16) + (0 * 8) + (1 * 4) + (0 * 2) + (0 * 1) = 1001 0100.

В таблице:

Двоичный символ 1 0 0 1 0 1 0 0
* Значение символа 128 64 32 16 8 4 2 1
= Результат (148) 128 0 0 16 0 4 0 0

Другой пример

Переведем 117 в бинарную систему, используя способ №1:

117 / 2 = 58 r1
58 / 2 = 29 r0
29 / 2 = 14 r1
14 / 2 = 7 r0
7 / 2 = 3 r1
3 / 2 = 1 r1
1 / 2 = 0 r1

Запишем число с остатков (снизу вверх), 117 = 111 0101 в двоичной системе.

А теперь используя способ №2:

Наибольшее число, умноженное на 2, которое меньше 117 — это 64.

117 >= 64? Да, поэтому 64 бит равен 1. 117 − 64 = 53.
53 >= 32? Да, поэтому 32 бит равен 1. 53 − 32 = 21.
21 >= 16? Да, 16 бит равен 1. 21 − 16 = 5.

5 >= 8? Нет, 8 бит равен 0.
5 >= 4? Да, 4 бит равен 1. 5 − 4 = 1.
1 >= 2? Нет, 2 бит равен 0.
1 >= 1? Да, 1 бит равен 1.

117 = 111 0101.

Сложение двоичных чисел

В некоторых случаях (одно из них мы рассмотрим ниже) может пригодиться возможность сложить два двоичных числа. Это на удивление легко (может быть, даже проще, чем сложение десятичных чисел), хотя поначалу может показаться немного странным, но к этому нужно просто привыкнуть.

Рассмотрим два небольших двоичных числа:

0110 (6 в десятичной системе) +
0111 (7 в десятичной системе)

Применим сложение. Во-первых, числа нужно записать в столбик, как показано выше. Затем, справа налево, мы слагаем каждый столбец цифр, как будто это десятичные числа. Так как в бинарной системе есть только два числа: 0 и 1, то есть только 4 возможных результата:

 0 + 0 = 0

 0 + 1 = 1

 1 + 0 = 1

 1 + 1 = 0, 1 переносим в следующую колонку

Начнем с первой колонки:

0110 (6 в десятичной системе) +
0111 (7 в десятичной системе)
----

   1

0 + 1 = 1. Легко.

Вторая:

 1
0110 (6 в десятичной системе) +
0111 (7 в десятичной системе)
----

  01

1 + 1 = 0, 1 остается в памяти, до следующей колонки.

Третья:

11
0110 (6 в десятичной системе) +
0111 (7 в десятичной системе)
----

 101

А вот здесь уже немного сложнее. Обычно 1 + 1 = 0 и остается единица, которую мы переносим в следующую колонку. Тем не менее, у нас уже есть 1 из предыдущего столбца и нам нужно добавить еще 1. Что делать? А делать вот что: 1 остается, а еще 1 переносим дальше.

Последняя колонка:

11
0110 (6 в десятичной системе) +
0111 (7 в десятичной системе)
----
1101

0 + 0 = 0, но так как есть еще 1, то результат – 1101. 13 = 1101.

А вы спросите, а как добавить десятичную 1 к любому другому двоичному числу (например, к 1011 0011)? Точно так же, как мы это делали выше, только нижнее число – это двоичная единица.

       1 (переносим в следующую колонку)
1011 0011 (двоичное число)
0000 0001 (1 в двоичной системе)
---------
1011 0100

Числа signed и two’s complement

В примерах выше мы работали только с целыми числами unsigned, которые могут быть только положительными. Сейчас же мы рассмотрим то, как работать с числами signed, которые могут быть и отрицательными.

С целыми числами signed используется метод two’s complement. Он означает, что самый левый (самый главный) бит используется в качестве знакового бита. Если значение знакового бита — 0, то число положительное, если 1, то число отрицательное.

Положительные числа signed хранятся так же, как и положительные числа unsigned (со знаковым битом 0). А вот отрицательные числа signed хранятся в виде обратных положительных чисел, плюс 1. Например, переведем -5 с десятичной систему в бинарную, учитывая two’s complement:

Сначала выясняем бинарное представление 5: 0000 0101
Затем инвертируем все биты (преобразуем в противоположные): 1111 1010
Затем добавляем 1: 1111 1011

Конвертация -76 в двоичную систему:

Представление положительного числа 76: 0100 1100
Инвертируем все биты: 1011 0011
Добавляем 1: 1011 0100

Почему мы добавляем 1? Рассмотрим это на примере 0. Если отрицательное значение представить просто в виде противоположной величины положительного числа, то 0 будет иметь два представления: 0000 0000 (положительный ноль) и 1111 1111 (отрицательный ноль). При добавлении 1, в 1111 1111 произойдет переполнение, и значение поменяется на 0000 0000. Добавление 1 предотвращает 0 от наличия двух представлений и упрощает внутреннюю логику, необходимую для арифметических вычислений с отрицательными числами.

Перед тем, как конвертировать бинарное число (учитывая two’s complement) обратно в десятичную систему, нужно сначала посмотреть на знаковый бит. Если это 0, то смело используйте способы выше для целых чисел unsigned. Если же это значение 1, то тогда нужно инвертировать все биты, затем добавить, конвертировать в десятичную систему, и уже после этого менять знак десятичного числа на отрицательный (потому что знаковый бит изначально был отрицательным).

Например, переведем 1001 1110 (учитывая two’s complement) в десятичное число:

Имеем: 1001 1110
Инвертируем биты: 0110 0001
Добавляем 1: 0110 0010
Конвертируем в десятичную систему: (0 * 128) + (1 * 64) + (1 * 32) + (0 * 16) + (0 * 8) + (0 * 4) + (1 * 2) + (0 * 1 ) = 64 + 32 + 2 = 98

Так как исходный знаковый бит был отрицательным, то результат: -98.

Почему важен тип данных?

Рассмотрим бинарное значение 1011 0100. Что это за число в десятичной системе? Вы, наверное, скажите 180, и если бы это было стандартное двоичное число unsigned, вы были бы правы. Однако, если здесь используется метод two’s complement, то результат будет другой: -76. Плюс значение может быть еще другим, если оно закодировано каким-то третьим способом.

Так как же C++ знает, в какое число переводить 1011 0100: 180 или -76?

Еще в уроке об инициализации, присвоении и определении, мы говорили: «Когда вы присваиваете значению тип данных, компилятор и процессор заботится о деталях кодирования этого значения в соответствующую последовательность битов определенного типа данных. Когда вы просите ваше значение обратно, оно «восстанавливается» из последовательности битов в памяти».

Тип переменной используется для конвертации бинарного представления числа обратно в ожидаемую форму. Так что, если тип переменной был unsigned integer, то компилятор знал, что 1011 0100 — это стандартное бинарное число, и его десятичная форма 180. Если же тип переменной был целочисленный signed, то компилятор знал, что 1011 0100 закодирован с помощью two’s complement и должно выводиться -76.

Тест

1) Переведите 0100 1101 в десятичную систему.

2) Переведите 93 в 8-битовое бинарное число unsigned.

3) Переведите -93 в 8-битовое бинарное число signed (используя two’s complement).

4) Переведите 1010 0010 в десятичное число unsigned.

5) Переведите 1010 0010 в десятичное число signed (используется two’s complement).

6) Напишите программу, которая просит пользователя ввести число от 0 до 255. Выведите его как 8-битовое бинарное число (формы #### ####). Не используйте побитовые операторы.

Подсказка 1: Воспользуйтесь способом № 2. Предполагается, что наименьшее число для сравнения — 128.

Подсказка 2: Напишите функцию для проверки входных чисел, являются ли они больше чисел умноженных на 2. Если это так, то выводится ‘1’ и возвращается результат (исходное число минус число для сравнения).

Ответы

Ответ 1

Двоичный символ 0 1 0 0 1 1 0 1
* Значение символа 128 64 32 16 8 4 2 1
= Результат (77) 0 64 0 0 8 4 0 1

Ответ: 77.

Ответ 2

Используя способ № 1:

93 / 2 = 46 r1
46 / 2 = 23 r0
23 / 2 = 11 r1
11 / 2 = 5 r1
5 / 2 = 2 r1
2 / 2 = 1 r0
1 / 2 = 0 r1

Остатки снизу вверх: 101 1101.

Используя способ № 2:

Наибольшее число, умноженное на 2, которое меньше 93 — это 64.

93 >= 64? Да, 64 бит равен 1. 93 — 64 = 29.
29 >= 32? Нет, 32 бит равен 0.
29 >= 16? Да, 16 бит равен 1. 29 — 16 = 13.
13 >= 8? Да, 8 бит равен 1. 13 — 8 = 5.
5 >= 4? Да, 4 бит равен 1. 5 — 4 = 1.
1 >= 2? Нет, 2 бит равен 0.
1 >= 1? Да, 1 бит равен 1.

Ответ: 0101 1101.

Ответ 3

Мы уже знаем из предыдущего примера, что 93 — это 0101 1101.

Так как используется two’s complement, то инвертируем биты: 1010 0010.

И добавляем 1: 1010 0011.

Ответ 4

Работая справа налево:

1010 0010 = (0 * 1) + (1 * 2) + (0 * 4) + (0 * 8) + (0 * 16) + (1 * 32) + (0 * 64) + (1 * 128) = 2 + 32 + 128 = 162.

Ответ: 162.

Ответ 5

Имеем: 1010 0010
Инвертируем биты: 0101 1101
Добавляем 1: 0101 1110

Конвертируем в десятичную систему: 16 + 64 + 8 + 4 + 2 = 94
Так как здесь используется two’s complement и исходный левый бит отрицательный, то результат: -94

Ответ: -94.

Ответ 6

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (9 оценок, среднее: 4,56 из 5)
Загрузка...
Поделиться в:
Подписаться на обновления:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *