В математике используется естественная форма записи целого числа, при которой непосредственно перед старшей значащей цифрой числа помещается знак плюс (+) или минус (-), а длина записи определяется величиной числа.
В компьютере это не так. Практически все современные цифровые компьютеры используют двоичную систему счисления, в которой используются только два символа - цифры 0 и 1. При этом одной из важнейших характеристик любого компьютера является длина используемого слова (т.е. количество двоичных разрядов в нем). Поэтому в компьютере, независимо от величины целого числа, его код всегда имеет фиксированное количество двоичных цифр.
При записи двоичных чисел со знаком в их формате необходимо предусмотреть два поля, определяющих знак и модуль числа (рис.1). Под знак числа отводится один двоичный разряд, при этом для задания знака используется следующее правило: знак плюс изображается цифрой 0, знак минус – цифрой 1, а цифра, изображающая знак, всегда записывается самой первой в записи числа. Остальные разряды определяют модуль числа. Способы представления модуля числа могут быть разные.
|
|
При выборе способа хранения целых чисел в памяти компьютера разработчики исходят из того, чтобы этот способ: – не требовал усложнения архитектуры процессора для выполнения арифметических операций с отрицательными числами; – не усложнял арифметические действия; – хранил бы одинаковое количество положительных и отрицательных чисел. |
Рис. 1. Представление |
В истории развития компьютеров использовались несколько вариантов представления целых чисел со знаком. Рассмотрим разные методы представления (слайды 6-7).
Прямой код
При записи числа в прямом коде старший разряд является знаковым разрядом. Его нулевое значение определяет положительное число или положительный ноль, а единичное – отрицательное число или отрицательный ноль. В остальных разрядах записывается двоичное представление модуля числа. Например, число -5 в 8-разрядном формате, использующем прямой код, будет выглядеть так: 10000101. Другие примеры чисел в прямом коде приведены ниже.
Число Прямой код
+1101 (+13) 0000 1101
+1011101 (+93) 0101 1101
- 1101 (-13) 1000 1101
В n -разрядном формате таким способом можно представить числа в диапазоне [ -(2n-1 – 1); 2n-1 - 1 ] (рис.2).
Рис. 2. Представление двоичных чисел в прямом коде
Достоинства представления чисел с помощью прямого кода
· Получить прямой код числа достаточно просто.
|
|
· Из-за того, что 0 обозначает +, коды положительных чисел при беззнаковом кодировании остаются неизменными.
· Количество положительных чисел равно количеству отрицательных.
Недостатки представления чисел с помощью прямого кода
· Правила счета для положительных и отрицательных чисел различаются, т.к. в прямом коде при переходе значения числа через ноль (рис. 2), происходит скачкообразное изменение кода.
· Выполнение арифметических операций с отрицательными числами требует усложнения архитектуры центрального процессора (например, для вычитания невозможно использовать сумматор, для этого необходима отдельная специальная схема).
· Существуют два нуля: +0 (000...000) и -0 (100...000), из-за чего усложняется арифметическое сравнение.
Из-за весьма существенных недостатков прямой код используется очень редко. Например, прямой код может использоваться при хранении чисел в памяти компьютера, а также при выполнении операций умножения и деления.
Код со сдвигом
Код со сдвигом – это такой способ представления целых чисел со знаком, при котором 000…0 интерпретируется как минимально возможное отрицательное число, а 111…1 – как максимальное положительное число. Для кодирования числа в n -разрядном формате нужно к нему прибавить величину сдвига 2n-1, для декодирования – вычесть эту величину.
Например, число -5 в 8-разрядном формате, использующем код со сдвигом, превратится в -5 + 128 = 123, то есть будет выглядеть так: 01111011. Другие примеры чисел в коде со сдвигом приведены ниже.
Число Код со сдвигом
+1101 (+13) 13+128=141 1000 1101
+1011101 (+93) 93+128=221 1101 1101
- 1101 (–13) -13+128=115 0111 0011
По сути, при таком кодировании:
1) к кодируемому числу прибавляют 2n-1;
2) переводят получившееся число в двоичную систему счисления.
В n -разрядном формате таким способом можно представить числа в диапазоне [ -2n-1; 2n-1 - 1 ] (рис.3).
Рис. 3. Представление двоичных чисел в коде со сдвигом
Достоинства представления чисел с помощью кода со сдвигом
· Не требуется усложнение архитектуры процессора.
· Нет проблемы двух нулей: положительного и отрицательного.
Недостатки представления чисел с помощью кода со сдвигом
· При арифметических операциях нужно учитывать смещение, то есть проделывать на одно действие больше (например, после “обычного” сложения двух чисел у результата будет двойное смещение, одно из которых необходимо вычесть).
· Ряды положительных и отрицательных чисел несимметричны.
Из-за необходимости усложнения арифметических операций код со сдвигом для представления целых чисел используется не часто, но зато применяется для хранения порядка вещественного числа в формате с плавающей запятой.
Обратный код
Еще одним способом представления целых чисел со знаком является обратный код. Алгоритм получения обратного кода числа следующий:
– если число положительное, то в старший разряд (являющийся знаковым) записывается 0, а далее записывается само число (т.е. совпадает с прямым кодом);
– если число отрицательное, то в знаковый разряд записывается 1, а в остальные разряды - инвертированное значение модуля числа (1 меняем на 0, а 0 меняем на 1);
– если число является нулем, то его можно представить двумя способами: +0 (000...000) или -0 (111...111).
Рис. 4. Представление двоичных чисел в обратном коде
Таким образом, д ля неотрицательных чисел обратный код двоичного числа имеет тот же вид, что и запись неотрицательного числа в прямом коде.
Для отрицательных чисел обратный код получается из неотрицательного числа в прямом коде путем инвертирования всех разрядов.
Например, для представления числа -5 в двоичном
8-разрядном обратном коде нужно инвертировать прямой код модуля -5 (00000101), в результате чего получим 11111010. Другие примеры чисел в обратном коде приведены ниже.
|
|
Число Обратный код
+1101 (+13) 0000 1101
+1011101 (+93) 0101 1101
-1101 (–13) 1111 0010
В n -разрядном формате с использованием обратного кода можно представить числа в диапазоне [ -(2n-1 – 1); 2n-1 - 1 ] (рис.4).
Достоинства представления чисел с помощью обратного кода
· Простое получение кода отрицательных чисел.
· Из-за того, что 0 обозначает +, коды положительных чисел при беззнаковом кодировании остаются неизменными.
· Количество положительных чисел равно количеству отрицательных.
· И к положительным, и к отрицательным числам можно применять одни и те же правила, а операцию вычитания A-B можно заменить операцией сложения чисел A+(-B).
· Простое восстановление прямого кода отрицательного числа из обратного кода: для этого надо все разряды, кроме знакового, инвертировать.
Недостатки представления чисел с помощью обратного кода
· Существуют два нуля: положительный (+0) и отрицательный (-0).
· Выполнение арифметических операций с отрицательными числами требует усложнения архитектуры центрального процессора.
Дополнительный код
Чаще всего для представления отрицательных чисел используется дополнительный код. Алгоритм получения дополнительного кода числа следующий:
– если число неотрицательное, то в старший разряд (являющийся знаковым) записывается 0, а далее записывается само число (т.е. совпадает с прямым кодом);
– если число отрицательное, то все разряды модуля числа инвертируются (т.е. формируется обратный код), к инвертированному числу прибавляется 1, а в знаковый разряд записывается 1.
Например, для представления числа -5 в двоичном
8-разрядном дополнительном коде нужно инвертировать прямой код модуля -5 (0000101), затем к полученному обратному коду (1111010) прибавить 1 (получаем 1111011), и приписать 1 в качестве знакового разряда, в результате чего получим 11111011. Другие примеры чисел в дополнительном коде приведены ниже.
Число Дополнительный код
|
|
+1101 (+13) 0000 1101
+1011101 (+93) 0101 1101
-1101 (–13) 1111 0011
Рис. 5. Представление двоичных чисел в дополнительном коде
Для получения из дополнительного кода самого числа нужно инвертировать все разряды кода и прибавить к результату 1. Можно проверить правильность, сложив дополнительный код с самим числом: результат должен быть равен 2n. Переведём 11111011 обратно. Инвертируем – получаем 00000100, прибавляем 1 - получаем 00000101 – модуль исходного числа -5.
В n -разрядном формате с использованием обратного кода можно представить числа в диапазоне [ -2n-1; 2n-1 - 1 ] (рис.5).
Достоинства представления чисел с помощью дополнительного кода
· Нет проблемы двух нулей, нулевое значение изображается только одной комбинацией.
· Обеспечивается естественный переход через ноль (рис.5).
· Достаточно простое получение кода отрицательных чисел.
· Простое восстановление прямого кода числа из дополнительного, для чего нужно полностью повторить (и именно в том же порядке!) действия, используемые для перевода из прямого кода в дополнительный: сначала все разряды, кроме знакового, заменить на противоположные, а затем прибавить 1.
· Единообразная реализация операции сложения чисел разных знаков (алгебраическое сложение), а операцию вычитания можно свести к операции сложения заменой знака вычитаемого на обратный. Это существенно упрощает архитектуру процессора и увеличивает скорость выполнения операций.
Недостатки представления чисел с помощью дополнительного кода
· Ряды положительных и отрицательных чисел несимметричны, но это не так важно: с помощью дополнительного кода достигаются гораздо более важные результаты.
· Числа в дополнительном коде нельзя сравнивать как беззнаковые или вычитать без расширения разрядности.
Несмотря на указанные недостатки, дополнительные коды в современных вычислительных системах используется чаще всего.
Таким образом, во всех трех основных кодах положительные числа выглядят одинаково (табл. 1). Различия в форме записи отрицательных чисел в прямом, обратном и дополнительном кодах касаются только способа представления модуля числа, а место расположения знакового разряда остается неизменным (слайд 8).
Таблица 1. Примеры двоичного представления целых чисел в разных кодах
Десятичное представление | Двоичное представление (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 |
Таблица 2. Характеристики форматов целых чисел
Название | Название | Диапазон | Размер переменной, бит | |
Visual Basic | C++ | |||
Знаковый целый | SByte | signed char | -128… 127 | 8 |
Short | short | -32768… 32767 | 16 | |
Integer | int | -2147483648… 2147483647 | 32 | |
Long | long | -9223372036854775808… 9223372036854775808 | 64 | |
Беззнаковый целый | Byte | unsigned char | 0... 255 | 8 |
UShort | unsigned short | 0… 65535 | 16 | |
UInteger | unsigned int | 0… 4294967295 | 32 | |
ULong | unsigned long | 0… 18446744073709551615 | 64 |
В современных ПК отрицательные целые числа представляются в дополнительном коде.В табл. 2 приведены характеристики форматов целых чисел, поддерживаемых во всех универсальных языках программирования, в частности, Visual Basic и C++ (слайд 9).