Информатика и технология программирования

       

Представление отрицательных чиселДополнительный код


Форма представления целых со знаком выбрана таким образом, чтобы заменить отрицательные числа положительными, но из другого диапазона. Тогда числа со знаком превращаются в беззнаковые и для работы с ними можно использовать часть команд для формы представления целых без знака. Интересно, что такой "фокус" могут быть произведен в любой системе счисления. Продемонстрируем его для начала в десятичной.

Пусть имеется 3-разрядное десятичное число со знаком. Представим его в следующем виде:



-добавим слева еще одну цифру -знак числа, принимающую всего два значения: 0 -плюс, 1 -минус;



-положительные числа представляются обычным образом;



-каждая цифра отрицательного числа заменяется на дополнение ее до n-1, где n -основание системы счисления. Для десятичной системы -это дополнение до 9, то есть цифра, которая в сумме с исходной дает 9;



-к полученному числу добавляется 1.

Такое представление отрицательных чисел называется дополнительным кодом. Он обладает одним замечательным свойством: сложение чисел в дополнительном коде по правилам сложения целых без знака дает корректный результат, который также получается в дополнительном коде. Убедимся в этом:

.


- 3 8 6 - отрицательное число
1 6 1 3 - дополнение каждой цифры до 9
1 6 1 4 - добавление 1
___________________________________________
512 - 386 =
0 5 1 2
+ 1 6 1 4
_______
2 1 2 6 - для знака используется 0 или 1
0 1 2 6 (переполнение)
___________________________________________
119 - 386 =
0 1 1 9
+ 1 6 1 4
_______
1 7 3 3 - результат в дополнительном коде
- 2 6 6 - дополнение каждой цифры до 9
- 2 6 7 - добавление 1

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

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


-взять абсолютное значение числа в двоичной системе;


-инвертировать все разряды, включая знаковый; -добавить 1.

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

.

положительное число
15 - знаковый разряд
14-0 - абсолютное значение числа в двоичной системе
_______________________________________
0 0 0 0 0 1 1 0 1 1 0 1 1 0 0 0
_______________________________________
+ 0 6 D 8

.

отрицательное число в дополнительном коде
_______________________________________
1 1 1 1 1 0 0 1 0 0 1 0 0 1 1 1 инверсия машинного слова
_______________________________________
F 9 2 7
_______________________________________
1 1 1 1 1 0 0 1 0 0 1 0 1 0 0 0 добавление 1
_______________________________________
F 9 2 8



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

.

Целое со знаком Значение в дополнительном коде
0 0
1 1
... ...
+32766 0x7FFE
+32767 0x7FFF
-1 0xFFFF
-2 0xFFFE
-16 0xFFF0
-32767 0x8001
не определено (-0) 0x8000





Как видим, положительные числа представлены аналогично беззнаковым. Машинное слово со всеми разрядами, установленными в 1, соответствует значению -1, а затем по убыванию - -2,-3 и т.д..

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

.

Дополнение 6 = Дополнение 0110 = 1001 = 9

.

24-66 = 0x18-0x42 = 0x18+(-0x42) = 0x18+0xFFBD+1 =

.

0x18+0xFFBE = 0xFFD6 = -(0x0029 + 1) = -0x2A = - 42





Содержание раздела