Как сделать дополнительный код
Прямой, обратный и дополнительный код числа
Зачем был нужен дополнительный код?
Как получить дополнительный код?
Давайте посмотрим, как получается дополнительный код для двоичной системы счисления. Вначале зададимся разрядностью регистра, в котором будет храниться наше число. Пусть, для примера, мы будем работать с 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 разрядах равно 
| Десятичное представление | Код двоичного представления (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).