Как сделать дополнительный код
Прямой, обратный и дополнительный код числа
Зачем был нужен дополнительный код?
Как получить дополнительный код?
Давайте посмотрим, как получается дополнительный код для двоичной системы счисления. Вначале зададимся разрядностью регистра, в котором будет храниться наше число. Пусть, для примера, мы будем работать с 8-ми разрядными числами. Возьмем, опять же для примера, число двенадцать и запишем его в двоичной системе счисления: 1100. Теперь впишем его в 8-ми разрядный регистр, где старшие, незадействованные в числе, разряды имеют нулевое значение (нумерация разрядов начинается с нуля).
Разр. | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
12 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
Такая запись соответствует 8-ми разрядному прямому коду числа двенадцать. А теперь проинвертируем все разряды регистра, т.е. заменим 0 на 1 и 1 на 0. и получим обратный код.
Разр. | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
12обр | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
Прибавив к числу в обратном коде единицу, получаем искомый дополнительный код.
Разр. | c | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1 | 1 | ||||||||
12обр | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | |
+ | 1 | ||||||||
12доп | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
Попробуем выполнить операцию вычитания нашего числа (двенадцать) из двадцати девяти с помощью сложения. Для этого впишем двоичное представление числа двадцать девять в 8-ми разрядный регистр и прибавим к нему дополнительный код, полученный ранее из числа двенадцать. Возникающий при этом перенос из самого старшего разряда игнорируем.
Разр. | c | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1 | 1 | 1 | 1 | 1 | 1 | ||||
29 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | |
12доп | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | |
17 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
Мы видим, что результирующая сумма есть двоичное число семнадцать и это действительно соответствует разности чисел двадцать девять и двенадцать.
Представление чисел с разными знаками
Идея состояла в том, чтобы хранить и обрабатывать положительные числа в прямом коде, а отрицательные в дополнительном. Необходимо было только как-то различать какое число перед нами положительное или отрицательное. Давайте, для наглядности сравним, как выглядят регистры с положительными числами и регистры с соответствующими им отрицательными числами, записанными в дополнительном коде.
Число | Код |
3 | 00000011 |
5 | 00000101 |
9 | 00001001 |
-3 | 11111101 |
-5 | 11111011 |
-9 | 11110111 |
Из анализа таблицы видно, что положительные числа начинаются с нулей, а отрицательные с единиц, что и позволяет в нашем примере отличать их по знаку. Но мы выбрали, для примера, небольшие положительные числа, в старшем разряде регистра которых изначально нет единицы. Но для числа «212» и соответственно «-212» это правило уже не срабатывает, так как число 212 изначально в старшем разряде регистра содержит единицу 21210 = 110101002.
Разр. | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
212 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 |
Однако, наша модель чисел с разными знаками всегда будет работать, если запретить пользоваться числами, модуль которых содержит единицу в старшем разряде регистра. Для 8-ми разрядного регистра это числа, модуль которых не превышает 127. Старший разряд регистра, при этом, просто указывает знак и поэтому, в данной модели представления чисел, его называют знаковым разрядом.
Сложение чисел с разными знаками
Переведем их модули в двоичную систему счисления и запишем в 8-ми разрядные регистры. 2110 = 101012 ; 3010 = 111102
Разр. | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
21 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
Разр. | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
30 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |
Чтобы получить число противоположное, по знаку, числу «30» возьмем от последнего дополнительный код. Сначала получим обратный код, инвертируя все разряды числа.
Разр. | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
30обр | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
Теперь прибавим единицу и получим дополнительный код.
Разр. | c | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1 | |||||||||
30обр | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | |
+ | 1 | ||||||||
30доп | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 |
Разр. | c | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
21 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | |
30доп | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | |
C | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 |
Проанализируем полученный результат. Мы видим, что в старшем (знаковом) разряде результата содержится единица, следовательно, результат есть число отрицательное и поэтому представлено оно в дополнительном коде. Значение этого числа сразу неочевидно и чтобы понять, что это за число, нам необходимо узнать его модуль.
Из курса школьной математики известно, что модуль положительного числа есть само число, а модуль отрицательного числа есть число ему противоположное. Поэтому нам нужно получить число противоположное результату, а это мы уже знаем как сделать, нужно взять от него дополнительный код.
Разр. | c | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Сi | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | |
+ | 1 | ||||||||
9 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
Разр. | c | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1 | 1 | 1 | |||||||
30доп | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | |
40 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | |
10 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
Итоги, уточнеия и обобщения о кодах
Число | Прямой код | Обратный код | Дополнительный код |
0 | 00000000 | 00000000 | 00000000 |
1 | 00000001 | 00000001 | 00000001 |
-1 | 10000001 | 11111110 | 11111111 |
5 | 00000101 | 00000101 | 00000101 |
-5 | 10000101 | 11111010 | 11111011 |
8 | 00001000 | 00001000 | 00001000 |
-8 | 10001000 | 11110111 | 11111000 |
120 | 01111000 | 01111000 | 01111000 |
-120 | 11111000 | 10000111 | 10001000 |
127 | 01111111 | 01111111 | 01111111 |
-127 | 11111111 | 10000000 | 10000001 |
Дополнительный код (представление числа)
Дополнительный код (дополнение до 2) двоичного числа получается добавлением 1 к младшему значащему разряду его дополнения до 1. [1]
Дополнение до 2 двоичного числа определяется как величина полученная вычитанием числа из наибольшей степени двух (из 2 N для N-битного дополнения до 2).
Содержание
Представление отрицательного числа в дополнительном коде
При записи числа в дополнительном коде старший разряд является знаковым. Если его значение равно 0, то в остальных разрядах записано положительное двоичное число, совпадающее с прямым кодом. Если число, записанное в прямом коде, отрицательное, то все разряды числа инвертируются, а к результату прибавляется 1. К получившемуся числу дописывается старший (знаковый) разряд, равный 1.
Двоичное 8-ми разрядное число со знаком в дополнительном коде может представлять любое целое в диапазоне от −128 до +127. Если старший разряд равен нулю, то наибольшее целое число, которое может быть записано в оставшихся 7 разрядах равно , что равно 127.
Десятичное представление | Код двоичного представления (8 бит) | ||
---|---|---|---|
прямой | обратный | дополнительный | |
127 | 01111111 | 01111111 | 01111111 |
1 | 00000001 | 00000001 | 00000001 |
0 | 00000000 | 00000000 | 00000000 |
-0 | 10000000 | 11111111 | — |
-1 | 10000001 | 11111110 | 11111111 |
-2 | 10000010 | 11111101 | 11111110 |
-3 | 10000011 | 11111100 | 11111101 |
-4 | 10000100 | 11111011 | 11111100 |
-5 | 10000101 | 11111010 | 11111011 |
-6 | 10000110 | 11111001 | 11111010 |
-7 | 10000111 | 11111000 | 11111001 |
-8 | 10001000 | 11110111 | 11111000 |
-9 | 10001001 | 11110110 | 11110111 |
-10 | 10001010 | 11110101 | 11110110 |
-11 | 10001011 | 11110100 | 11110101 |
-127 | 11111111 | 10000000 | 10000001 |
-128 | — | — | 10000000 |
Дополнительный код для десятичных чисел
Тот же принцип можно использовать и в компьютерном представлении десятичных чисел: для каждого разряда цифра X заменяется на 9−X, и к получившемуся числу добавляется 1. Например, при использовании четырёхзначных чисел −0081 заменяется на 9919 (9919+0081=0000, пятый разряд выбрасывается).
При применении той же идеи к привычной 10-ричной системе счисления получится (например, для гипотетического процессора использующего 10-ричную систему счисления):
10-ричная система счисления («обычная» запись) | 10-ричная система счисления, дополнительный код |
---|---|
. | . |
13 | 0013 |
12 | 0012 |
11 | 0011 |
10 | 0010 |
9 | 0009 |
8 | 0008 |
. | . |
2 | 0002 |
1 | 0001 |
0 | 0000 |
-1 | 9999 |
-2 | 9998 |
-3 | 9997 |
-4 | 9996 |
. | . |
-9 | 9991 |
-10 | 9990 |
-11 | 9989 |
-12 | 9988 |
. | . |
Преобразование в дополнительный код
Преобразование числа из прямого кода в дополнительный осуществляется по следующему алгоритму.
Пример. Преобразуем отрицательное число −5, записанное в прямом коде, в дополнительный. Прямой код числа −5, взятого по модулю:
Инвертируем все разряды числа, получая таким образом обратный код:
Добавим к результату 1
Допишем слева знаковый единичный разряд
Для обратного преобразования используется тот же алгоритм. А именно:
Инвертируем все разряды числа, получая таким образом обратный код:
Добавим к результату 1 и проверим, сложив с дополнительным кодом
p-адические числа
В системе p-адических чисел изменение знака числа осуществляется преобразованием числа в его дополнительный код. Например, если используется 5-ричная система счисления, то число, противоположное 1000. (1) равно 4444. (−1).