Дополнительный код (англ. two’s complement, иногда twos-complement) — наиболее распространённый способ представления отрицательных целых чисел в компьютерах. Он позволяет заменить операцию вычитания на операцию сложения и сделать операции сложения и вычитания одинаковыми для знаковых и беззнаковых чисел, чем упрощает архитектуру ЭВМ. В англоязычной литературе обратный код называют первым дополнением, а дополнительный код называют вторым дополнением.
Дополнительный код для отрицательного числа можно получить инвертированием его двоичного модуля (первое дополнение) и прибавлением к инверсии единицы (второе дополнение), либо вычитанием числа из нуля.
Дополнительный код (второе дополнение) двоичного числа получается добавлением 1 к младшему значащему разряду его первого дополнения.
[1]
Второе дополнение (англ. Two's complement) двоичного числа определяется как величина, полученная вычитанием числа из наибольшей степени двух (из 2N для N-битного второго дополнения).
При записи числа в дополнительном коде старший разряд является знаковым. Если его значение равно 0, то в остальных разрядах записано положительное двоичное число, совпадающее с прямым кодом.
Двоичное 8-разрядное число со знаком в дополнительном коде может представлять любое целое в диапазоне от −128 до +127. Если старший разряд равен нулю, то наибольшее целое число, которое может быть записано в оставшихся 7 разрядах, равно .
Примеры:
| Десятичное представление |
Двоичное представление (8 бит) | ||
|---|---|---|---|
| прямой | обратный | дополнительный | |
| 127 | 0111 1111 | 0111 1111 | 0111 1111 |
| 1 | 0000 0001 | 0000 0001 | 0000 0001 |
| 0 | 0000 0000 | 0000 0000 | 0000 0000 |
| -0 | 1000 0000 | 1111 1111 | --- |
| -1 | 1000 0001 | 1111 1110 | 1111 1111 |
| -2 | 1000 0010 | 1111 1101 | 1111 1110 |
| -3 | 1000 0011 | 1111 1100 | 1111 1101 |
| -4 | 1000 0100 | 1111 1011 | 1111 1100 |
| -5 | 1000 0101 | 1111 1010 | 1111 1011 |
| -6 | 1000 0110 | 1111 1001 | 1111 1010 |
| -7 | 1000 0111 | 1111 1000 | 1111 1001 |
| -8 | 1000 1000 | 1111 0111 | 1111 1000 |
| -9 | 1000 1001 | 1111 0110 | 1111 0111 |
| -10 | 1000 1010 | 1111 0101 | 1111 0110 |
| -11 | 1000 1011 | 1111 0100 | 1111 0101 |
| -127 | 1111 1111 | 1000 0000 | 1000 0001 |
| -128 | --- | --- | 1000 0000 |
Тот же принцип можно использовать и в компьютерном представлении десятичных чисел: для каждого разряда цифра 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:
0101
Инвертируем все разряды числа, кроме знакового, получая таким образом обратный код (первое дополнение) отрицательного числа -5:
1010
Добавим к результату 1, получая таким образом дополнительный код (второе дополнение) отрицательного числа -5:
1011
Для преобразования отрицательного числа -5, записанного в дополнительном коде, в положительное число 5, записанное в прямом коде, используется похожий алгоритм. А именно:
1011
Инвертируем все разряды отрицательного числа -5, получая таким образом положительное число 4 в прямом коде:
0100
Добавив к результату 1 получим положительное число 5 в прямом коде:
0101
И проверим, сложив с дополнительным кодом
0101 + 1011 = 10000, пятый разряд выбрасывается.
В системе p-адических чисел изменение знака числа осуществляется преобразованием числа в его дополнительный код. Например, если используется 5-ичная система счисления, то число, противоположное 00015 (110), равно 44445 (−110).
if (a < 0) then
a := ((not a) or 128) + 1;
1 int convert(int a) {
2 if (a < 0)
3 a = ~(-a) + 1;
4 return a;
5 }
Если происходит чтение данных из файла или области памяти, где они хранятся в двоичном дополнительном коде (например, файл WAVE), может оказаться необходимым преобразовать байты. Если данные хранятся в 8 битах, необходимо, чтобы значения 128-255 были отрицательными.
byte b1 = 254; //11111110 (бинарное)
byte b2 = 121; //01111001 (бинарное)
byte c = 1<<(sizeof(byte)*8-1); //2 возводится в степень 7. Результат: 10000000 (бинарное)
byte b1Conversion=(c ^ b1) + c; //Результат: -2. А фактически, двоичный дополнительный код.
byte b2Conversion=(c ^ b2) + c; //Результат остаётся 121, потому что знаковый разряд - ноль.
Расширение знака (англ. Sign extension) — операция над двоичным числом, которая позволяет увеличить разрядность числа с сохранением знака и значения. Выполняется добавлением цифр со стороны старшего значащего разряда. Если число положительное (старший разряд равен 0), то добавляются нули, если отрицательное (старший разряд равен 1) — единицы.
| Десятичное число | Двоичное число
(8 разрядов) |
Двоичное число
(16 разрядов) |
|---|---|---|
| 10 | 0000 1010 |
0000 0000 0000 1010 |
| −15 | 1111 0001 |
1111 1111 1111 0001 |
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .