Если к двоичному числу без знака добавить знаковый разряд то получится

Рассматривая представление чисел в различных системах счисления, мы, по умолчанию, считали, что все они не имеют знака, т. е. среди них нет отрицательных. Действительно такие числа находят широкое применение. Беззнаковыми целыми являются адреса ячеек памяти, коды символов, коды операций, управляющие коды различных устройств ЭВМ, операнды логических команд. Для беззнаковых чисел, представленных в двоичной системе счисления, используется весь диапазон чисел, записываемых в ячейку заданной разрядности. Например, в двоичном восьмиразрядном числе все разряды использу ются для отображения цифр числа. Поэтому беззнаковые числа размером байт имеют диапазон

00000000Ь. 11111ШЬ = 00h. FFh = 0d. 255d.

Беззнаковые числа размером два байта имеют диапазон:

0000000000000000Ь. Ш11Ш11Ш111Ь = 0000h. FFFFh =

= 0d. (2 16 -l)d = 0d. 65535d,

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

Положительные целые числа со знаком — это 0 и все положительные целые числа.

Отрицательные целые числа со знаком — это все целые числа меньшие 0.

Числа со знаком можно представлять по-разному:

  • • в виде прямого двоичного кода;
  • • в виде обратного двоичного кода (дополнения до единицы);
  • • в виде дополнительного двоичного кода (дополнения до двух).

Во всех этих представлениях для кодирования знака используется старший разряд (старший бит) разрядной сетки, называемый, в этом случае, знаковым (Signum — S). «0» в знаковом разряде соответствует знаку « + », а «1» соответствует знаку « — ». Физически этот бит ничем не отличается от других, все зависит от трактовки этого бита. В операциях со знаком он играет роль знакового разряда S, в беззнаковых операциях это значение старшего бита числа. Поэтому следует помнить, что в двоичном представлении целого числа со знаком для отображения самого числа отводится на один разряд меньше, чем имеется в разрядной сетке.

Прямой двоичный код числа со знаком Рпр(х) это позиционный двоичный код числа, который получается по правилам, рассмотренным выше в 1.1. К записанному двоичному числу слева добавляется знаковый разряд S. Если число положительное, то в знаковом разряде записывается «0», что соответствует знаку « + » . Если число отрицательное, то в знаковом разряде записывается «1», что соответствует знаку « — ».

Например, числа +6d и -6d, представленные в виде байта прямого двоичного кода РпР(х), выглядят так:

+6d = 00000110b;

-6d =10000110b.

Как видно, они отличаются только значением старшего (знакового) разряда.

Прямой код

Прямой код — способ представления двоичных чисел с фиксированной запятой. Главным образом используется для записи неотрицательных чисел

Как устроен двоичный код

Прямой код используется в двух вариантах.
В первом (основной) — для записи только неотрицательных чисел:

Неотрицательные числа в прямом коде

В этом варианте (для восьмибитного двоичного числа) мы можем записать максимальное число 255 (всего чисел 256 — от 0 до 255)

Второй вариант — для записи как положительных, так и отрицательных чисел.
В этом случае старший бит (в нашем случае — восьмой) объявляется знаковым разрядом (знаковым битом).
При этом, если:
— знаковый разряд равен 0, то число положительное
— знаковый разряд равен 1, то число отрицательное

Знаковый разряд прямого кода

В этом случае диапазон десятичных чисел, которые можно записать в прямом коде составляет от — 127 до +127:

Двоичные числа в прямом коде

Подводя итоги вопроса, не влезая в его дебри, скажу одно:
Прямой код используется главным образом для представления неотрицательных чисел.
Использование прямого кода для представления отрицательных чисел является неэффективным — очень сложно реализовать арифметические операции и, кроме того, в прямом коде два представления нуля — положительный ноль и отрицательный ноль (чего не бывает):

Обратный код

Обратный код — метод вычислительной математики, позволяющий вычесть одно число из другого, используя только операцию сложения.
Обратный двоичный код положительного числа состоит из одноразрядного кода знака (битового знака) — двоичной цифры 0, за которым следует значение числа.
Обратный двоичный код отрицательного числа состоит из одноразрядного кода знака (битового знака) — двоичной цифры 1, за которым следует инвертированное значение положительного числа.

Для неотрицательных чисел обратный код двоичного числа имеет тот же вид, что и запись неотрицательного числа в прямом коде.
Для отрицательных чисел обратный код получается из неотрицательного числа в прямом коде, путем инвертирования всех битов (1 меняем на 0, а 0 меняем на 1).
Для преобразования отрицательного числа записанное в обратном коде в положительное достаточного его проинвертировать.

При 8-битном двоичном числе — знаковый бит (как и в прямом коде) старший (8-й)

Двоичное число в обратном коде

Диапазон десятичных чисел, который можно записать в обратном коде от -127 до + 127

Арифметические операции с отрицательными числами в обратном коде:

1-й пример (для положительного результата)
Дано два числа:
100 = 0110 0100
-25 = — 0001 1001
Необходимо их сложить:
100 + (-25) = 100 — 25 = 75

1-й этап
Переводим число -25 в двоичное число в обратном коде:
25 = 0 001 1001
-25= 1 110 0110
и складываем два числа:
0 110 0100 (100) + 1 110 0110 (-25) = 1 0 100 1010, отбрасываем старшую 1 (у нас получился лишний 9-й разряд — переполнение), = 0 100 1010
2-й этап
Отброшенную в результате старшую единицу прибавляем к результату:
0 100 1010 + 1 = 0 100 1011 (знаковый бит = 0 , значит число положительное), что равно 75 в десятичной системе

2-й пример (для отрицательного результата)
Дано два числа:
5 = 0000 0101
-10 = — 0000 1010
Необходимо их сложить:
5 + (-10) = 5 — 10 = -5

1-й этап
Переводим число -10 в двоичное число в обратном коде:
10 = 0 000 1010
-10= 1 111 0101
и складываем два числа:
0 000 0101 (5) + 1 111 0101 (-10) = 1 111 1010 (знаковый бит = 1 , значит число отрицательное)

2-й этап
Раз результат получился отрицательный, значит число представлено в обратном коде.
Переводим результат в прямой код (путем инвертирования значения, знаковый бит не трогаем):
1 111 1010 —-> 1 000 0101
Проверяем:
1 000 0101 = — 0000 0101 = -5

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

FasmWorld Программирование на ассемблере FASM для начинающих и не только

Числа со знаком и дополнительный код

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

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

С отрицательными числами чуть сложнее. Исторически для представления отрицательных чисел в компьютерах использовались разные виды кодирования: прямой, обратный и дополнительный код. В настоящее время наиболее часто используется дополнительный код, в том числе и в процессорах x86.

Чтобы сделать из положительного числа отрицательное, необходимо проинвертировать все его биты (0 заменяем на 1, а 1 заменяем на 0) и затем к младшему разряду прибавить единицу. Например, представим -5 в дополнительном коде:

В обратную сторону переводится точно также

Синтаксис FASM

Для записи отрицательного числа в программе на ассемблере используется символ ‘-‘, например:

x db -5

Кстати, это работает и с числами в других системах счисления, и даже с символами

y db -25h z db -77o k db -101b s db -‘a’

y db -25h z db -77o k db -101b s db -‘a’

Со знаковыми и беззнаковыми числами нужно быть внимательным, потому что только вы знаете, какие числа используются в вашей программе! Процессору абсолютно по барабану, какие данные он обрабатывает, поэтому невнимательность может привести к ошибке. Один и тот же байт может интерпретироваться по-разному, в зависимости от того со знаком число или без. Например, числу со знаком -5 соответствует число без знака 251:

Диапазоны значений чисел со знаком и без

При программировании на ассемблере (как, впрочем, и на многих других языках) необходимо учитывать ещё один важный момент. А именно — ограничение диапазона представления чисел. Например, если размер беззнаковой переменной равен 1 байт, то она может принимать всего 256 различных значений. Это означает, что мы не сможем представить с её помощью число, больше 255 (111111112). Для такой же переменной со знаком максимальным значением будет 127 (011111112), а минимальным -128 (100000002). Аналогично определяется диапазон для 2- и 4-байтных переменных.

Кстати, так как процессор Intel 8086 был 16-битным и обрабатывал за одну команду 16-бит, то 16-битная переменная называется слово (word), а 32-битная — двойное слово (double word, dword). Эти названия сохранились в ассемблере даже для 32-битных процессоров (и в WIN32 API, например). И от них же происходят названия директив dw (Define Word) и dd (Define Dword). Ну а db — это Define Byte.

Для наглядности вот табличка диапазонов чисел:

Размер
переменной Число без знака Число со знакомmin max min max
байт00000000111111111000000001111111
0255-128127
слово00000000 0000000011111111 1111111110000000 0000000001111111 11111111
065 535-32 76832 767
двойное
слово
0000…00001111…11111000…00000111…1111
04 294 967 295-2 147 483 6482 147 483 647
и т.д.

Если результат какой-то операции выйдет за пределы диапазона представления чисел, то случится переполнение и результат будет некорректным. (Например, при сложении двух положительных чисел, можно получить отрицательное число!) Поэтому нужно быть внимательным при программировании и предусмотреть обработку таких ситуаций, если они могут возникнуть.

Комментарии:

ratiug
09-11-2010 10:38

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

xrnd
10-11-2010 17:31

Спасибо. Такие комментарии мне нравятся

oleg
15-11-2010 00:04

Только не операторы перехода, а операнды сравнения.

xrnd
15-11-2010 17:10

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

anton
16-02-2011 01:00

Приветствую, xrnd и всех. Такой вот вопрос замучил: почему при сложении 106+25=131 возникает переполнение, а в случае 2+129=131 нет ? Складываю в байтовом регистре, т.е. в обоих случаях получаю одно и то же отрицат. число.

xrnd
18-02-2011 13:21

Тут надо быть внимательным с флагами.
Дело в том, что числа со знаком и числа без знака складываются и вычитаются совершенно одинаково. Разница только в интерпретации флагов и знакового бита.

Флаг переполнения OF имеет смысл только для чисел со знаком.
Переполнение возникает в следующих случаях:
1. положительное + положительное = отрицательное
2. отрицательное + отрицательное = положительное

В этих случаях результат сложения некорректен. Например, два положительных числа должны давать в сумме положительное, а не отрицательное.

Если записать твои примеры в виде чисел со знаком, то всё становится понятным:
106+25 = -125 (переполнение!)
2 + (-127) = -125 (нет переполнения)

Для чисел без знака проверять переполнение нужно по флагу переноса CF. Если был перенос из старшего разряда, то результат вышел за допустимые пределы.

anton
18-02-2011 16:16

Значит, если подразумевается, что числа со знаком, поднятый of будет означать неверный результат, если же числа беззнаковые, на of можно не обращать внимания, а смотреть на cf. Спасибо, теперь понятно.

Денис
11-11-2011 16:16

я что то не понял при записи 101b=5 но при 010b получается 2. Так как при инвертации нельзя записать число с начальным нулем получается 10b
А при -5 получаеться 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1011b
я что то не понимаю вас

Sanya
03-05-2015 18:30

Имеются два числа: 11111011 и 11111011. Как ассемеблер понимает что нужно выводить отрицательное число или положительное?

Sammy
27-03-2018 11:28

Мне тоже интересно. Вопрос еще актуален, ответьте пожалуйста, о, гуру ассемблера

Пися Камушкин
18-07-2018 17:19

test ax,ax
во флаги будут помещены конкретные значения свойств числа, в том числе и s флаг, который и говорит о знаковом бите.

Kella
03-10-2018 16:26

По флагу жеж. Если есть флаг SF=1 то данное число отрицательное.

Никита
27-10-2018 23:47

Ассемблер никак не понимает, для него это одно и то же самое значение. Интерпретация ложится на программиста который это значение использует.
Например при сравнении двух чисел, записаных в регистры процессоа, с использованием команды cmp:
cmp ax, bx
процессор вычтет одно число из другого, и установит по результату вычитания значение флагов
ZF. SF, OF CF. Если надо интерпритировать сравнение как сравнение знаковых чисел, то проверяются одни флаги (ZF, OF), если как беззнаковые, то другие флаги (ZF, CF). Для удобства в ассемблере используется отдельные команды сравнения знаковых чисел (jl,jle, jg,jge) и беззнаковых (jb,jbe,ja,jae)

Николай
04-01-2019 13:33

Тут дело вообще не в ассемблере. Сложение/вычитание выполняется одинаково, но в завимисости от результата выставляются флаги SF(знаковый),CF(переноса),OF(переполнения).
Некоторые операторы учитывают знаки(переходы ja,jb), в противовес им jg,jl -считают числа беззнаковыми (http://asmworld.ru/spravochnik-komand/jcond/).
В остальных случаях флаги нужно учитывать самому.

Krol
07-02-2019 21:30

Всё зависит от алгоритма вывода. Последний бит — бит знака. Если его не считать, то получается число без знака, имеющее обычно диапазон [0.255]. Иначе, нужно выводить знак и остальные семь бит выводить в десятичной системе счисления (как я понимаю).
Подробнее разобрано тут: http://asmworld.ru/uchebnyj-kurs/022-vyvod-chisel-na-konsol/

Arct
16-06-2019 15:37

Ассемблер — никак… Это задача программиста на ассемблере…
А вот отдельные команды, IDIV (целочисленное деление со знаком) например, по наличию «1» в старшем (знаковом) разряде своих операндов.

Беззнаковые числа и числа со знаком

Рассматривая представление чисел в различных системах счисления, мы, по умолчанию, считали, что все они не имеют знака, т. е. среди них нет отрицательных. Действительно такие числа находят широкое применение. Беззнаковыми целыми являются адреса ячеек памяти, коды символов, коды операций, управляющие коды различных устройств ЭВМ, операнды логических команд. Для беззнаковых чисел, представленных в двоичной системе счисления, используется весь диапазон чисел, записываемых в ячейку заданной разрядности. Например, в двоичном восьмиразрядном числе все разряды использу ются для отображения цифр числа. Поэтому беззнаковые числа размером байт имеют диапазон

00000000Ь. 11111ШЬ = 00h. FFh = 0d. 255d.

Беззнаковые числа размером два байта имеют диапазон:

0000000000000000Ь. Ш11Ш11Ш111Ь = 0000h. FFFFh =

= 0d. (2 16 -l)d = 0d. 65535d,

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

Положительные целые числа со знаком — это 0 и все положительные целые числа.

Отрицательные целые числа со знаком — это все целые числа меньшие 0.

Числа со знаком можно представлять по-разному:

  • • в виде прямого двоичного кода;
  • • в виде обратного двоичного кода (дополнения до единицы);
  • • в виде дополнительного двоичного кода (дополнения до двух).

Во всех этих представлениях для кодирования знака используется старший разряд (старший бит) разрядной сетки, называемый, в этом случае, знаковым (Signum — S). «0» в знаковом разряде соответствует знаку « + », а «1» соответствует знаку « — ». Физически этот бит ничем не отличается от других, все зависит от трактовки этого бита. В операциях со знаком он играет роль знакового разряда S, в беззнаковых операциях это значение старшего бита числа. Поэтому следует помнить, что в двоичном представлении целого числа со знаком для отображения самого числа отводится на один разряд меньше, чем имеется в разрядной сетке.

Прямой двоичный код числа со знаком Рпр(х) это позиционный двоичный код числа, который получается по правилам, рассмотренным выше в 1.1. К записанному двоичному числу слева добавляется знаковый разряд S. Если число положительное, то в знаковом разряде записывается «0», что соответствует знаку « + » . Если число отрицательное, то в знаковом разряде записывается «1», что соответствует знаку « — ».

Например, числа +6d и -6d, представленные в виде байта прямого двоичного кода РпР(х), выглядят так:

+6d = 00000110b;

-6d =10000110b.

Как видно, они отличаются только значением старшего (знакового) разряда.

Прямой, обратный и дополнительный коды

Очень часто в вычислениях должны использоваться не только положительные, но и отрицательные числа.

Число со знаком в вычислительной технике представляется путем представления старшего разряда числа в качестве знакового .

Принято считать, что 0 в знаковом разряде означает знак «плюс» для данного числа, а 1 – знак «минус».

Число со знаком в 8-битной разрядной сетке

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

Применение дополнительного кода позволяет выполнить операцию алгебраического суммирования и вычитания на обычном сумматоре. При этом не требуется определения модуля и знака числа.

Прямой код представляет собой одинаковое представление значимой части числа для положительных и отрицательных чисел и отличается только знаковым битом. В прямом коде число 0 имеет два представления «+0» и «–0».

Обратный код для положительных чисел имеет тот же вид, что и прямой код, а для отрицательных чисел образуется из прямого кода положительного числа путем инвертирования всех значащих разрядов прямого кода. В обратном коде число 0 также имеет два представления «+0» и «–0».

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

Так, в восьмиразрядном представлении диапазон изменения чисел с учетом знака.

Таблица прямого, обратного и дополнительного кода 4-битных чисел. Для наглядности представления всего диапазона чисел примем, что сетка представления чисел 4-разрядная, где старший разряд (3) — знаковый, а 0-2 разряды содержат значение числа.

ЧислоПрямой кодОбратный кодДополнительный код
-81000
-7111110001001
-6111010011010
-5110110101011
-4110010111100
-3101111001101
-2101011011110
-1100111101111
0
0
1000
0000
1111
0000
0000
1000100010001
2001000100010
3001100110011
4010001000100
5010101010101
6011001100110
7011101110111

Прямой код двоичного числа

В системе представления в прямом коде число состоит из кода знака и модуля числа, причём обе эти части обрабатываются по отдельности.

Примеры прямого кода для правильных дробей:

Примеры прямого кода для целых чисел:

Представление чисел в прямом коде имеет существенный недостаток — формальное суммирование чисел с различающимися знаками даёт неверный результат. Пример — сложение двух чисел и . В прямом коде эти числа имеют вид: и . Очевидно, что результат должен быть равен -2, что в прямом коде может быть записано как 1.010. В то же время при непосредственном сложении получаем

то есть значение, существенно отличающееся от ожидаемого.

Процедура для корректного сложения чисел в прямом коде всё же существует, но она очень громоздка. Прямой код имеет ещё один недостаток — нуль имеет два различных представления, а именно и , что математически не имеет смысла.

По причине отмеченных недостатков в вычислительных машинах используется не прямой код, а обратный и дополнительный коды.

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

Обратный код двоичного числа

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

Примеры обратного кода для правильных дробей:

Примеры обратного кода для целых чисел:

Как нетрудно заметить, положительные числа в прямом и обратном кодах выглядят одинаково.

Хотя обратный код и позволяет решить проблему сложения и вычитания чисел с различными знаками, он имеет и недостатки. Во-первых, процесс суммирования чисел является двухэтапным, что увеличивает время выполнения этой операции. Во-вторых, как и в прямом коде, в обратном — два представления нуля: и .

Принятые сокращения

ДК — дополнительный код .

ОК — обратный код .

ПК — прямой код.

Правила двоичной арифметики

Двоичное сложение

В простейшем случае, для одноразрядных чисел, правила двоичного сложения имеют вид:

begin</p><p> _0\ 0\ cline 0\ end;;; begin _0\ 1\ cline 1\ end;;; begin _1\ 0\ cline 1\ end

1+1

При сложении ( ) возникает два случая:

  1. когда входной перенос равен 0, получаем 0+1+1=2_<10>=10_:

text<выходной перенос в следующий разряд></p><p>\ begin downarrow \ 1 gets text< входной перенос из предыдущего разряда>\ \ \ 1 \ uparrow \ end\

когда входной перенос равен 1, получаем 1+1+1=3_<10>=11_:

text<выходной перенос в следующий разряд></p><p>\ begin downarrow \ 1 gets text< входной перенос из предыдущего разряда>\ \ \ 1 \ uparrow \ end\ text

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

text<выходной перенос из старшего разряда></p><p>\ begin \ 1 1 1 getstext< перенос>\ _1 1 0 =61 \ 1 1 =15 \ cline 0 1 0 getstext< >сумма = 76\ \ end\ text

begin</p><p> 1 1 перенос >\ 0 0 1 1 1 =11\ cline 1 1 0 >сумма =52\ end

Двоичное вычитание

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

begin</p><p> _0 _1 _1 _? underline \ 0 1 0 /p><p> 0 1 getstext< изменение уменьшаемого в результате займа>\ _1 0 0 =33\ 1 1 =11\ cline 0 0 1 getstext< разность=22>\ end

begin</p><p> 0 0 1 gets text\ _1 1 0 =40\ 1 1 =27\ cline 0 1 0 gets text< >разность=13\ end

Очевидно, что как в десятичном, так и в двоичном коде, складывать значительно проще, чем вычитать. Поэтому большое распространение получила двоичная арифметика с учетом знаков чисел, где вычитание заменяется сложением чисел с учетом их знака. При этом уже не имеет значения соотношение чисел между собой, какое из них больше — вычитаемое или уменьшаемое. Знак разности получается автоматически.

Двоичная арифметика с учетом знаков чисел

Прямой, обратный и дополнительный коды

В двоичном коде знак числа представляет собой разряд, приписываемый слева от значащих разрядов числа. Знак » +» обозначается логическим 0, знак » -» — логической 1. Для наглядности все примеры будем рассматривать для целых чисел, отделяя знаковый разряд точкой.

Прямой код (ПК) и для отрицательных, и для положительных чисел образуется одинаково, простым дописыванием знакового разряда.

Так, в восьмиразрядном формате

Обратный код (ОК) для положительных чисел совпадает с прямым, т.е. к значащим разрядам приписывается знаковый разряд. Для отрицательных чисел значащие разряды инвертируются (нули заменяются на единицы, единицы — на нули), после чего приписывается знак.

Для того же числа обратный код имеет вид: (+ 10) = 0.0001010, (-10)=1.1110101.

Недостатком обратного кода является то, что одно и то же число (+0)и (-0)записывается по-разному: (+ 0) = 0.0000000, (-0)=1.1111111, что может вызвать нежелательное разночтение работы логической схемы. Поэтому предпочтительным является дополнительный код.

Дополнительный код (ДК) для положительных чисел совпадает с обратным и прямым, т.е. к значащим разрядам приписывается знаковый разряд. Для отрицательных чисел дополнительный код на 1 больше, чем обратный. После образования значащих разрядов приписывается знаковый разряд.

Для значащих разрядов отрицательного числа справедлива формула:

ДК=ОК+1.( 11.3)

(-0)

Напишем число в 7-разрядном дополнительном коде:

begin</p><p> _< >0 0 0 0 1 1 1 gets ОК \ 1 fbox 0 0 0 gets ДК \ end

(+0)=(-0)

Таким образом в дополнительном коде , следовательно, указанный недостаток обратного кода преодолен.

Рассмотрим образование дополнительного кода для числа 10. Для положительного числа (+ 10) = 0.0001010, а для отрицательного числа (-10) дополнительный ко д получается следующим образом:

begin</p><p> _< >0 0 0 0 1 0 0 gets ОК\ 1 1. 1 0 1 gets ДК end

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

Двоичная арифметика в дополнительном коде

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

ОК=ДК-1

  1. перевести десятичные числа в двоичный код;
  2. уравнять форматы полученных двоичных чисел;
  3. если знаки чисел одинаковые, добавить по одному резервному нулю слева от каждого числа во избежание переполнения;
  4. получить дополнительные коды чисел;
  5. приписать знаковые разряды;
  6. сложить полученные коды по правилам двоичного сложения;
  7. перенос из знакового разряда (если он есть) отбросить;
  8. результат получен в дополнительном коде, поэтому для проверки значащих разрядов отрицательного числа необходимо сделать вычисления, противоположные формуле (11.3): сначала вычислить обратный код по формуле , после чего произвести инверсию полученного числа.

Для наглядности возьмем два десятичных числа, например, 20и 55, и сделаем все возможные варианты вычислений:

20 + 55 = (+20) + (+55) = + 75

  • .

text<резервный разряд во избежание переполнения></p><p>\ begin \ 1 1 gets перенос\ _0. 0 0 0 =+20\ 0. 1 0 1 =+55\ cline 0. 0 1 1 gets результат\ uparrow end\ text

1001011_<2></p><p>Число положительное, поэтому <b>ОК=ПК</b>, для проверки числа нужно перевести его значащие разряды в десятичный код по (П3-2): =1+2+8+64= 75.

20 - 55 = (+20) + (-55) = - 35. Сначала получим дополнительный код отрицательного числа (-55):

begin</p><p> _< >1 0 1 gets ПК \ _0 1 0 gets ОК \ \ cline textto 0 1 0 gets ДК \ end

Здесь важно уяснить, что крайние левые нули в значащих разрядах сокращать нельзя, поскольку они являются значимыми. Иными словами, все вычисления для каждого примера производятся в неизменном формате, в данном случае в примере (б) — это шесть значащих разрядов, т.е. столько, сколько содержится в большем числе.

begin</p><p> _0. 1 1 0 0 1 0 =-55\ cline 1. 1 1 1 \ end\ text

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

begin</p><p> _0 1 0 gets ДК \ \ 0 1 0 gets ОК\ cline 1 0 1 gets ПК,\ end

100011 _<2></p><p>а затем уже перевести его в десятичный код по (П3-2): =1+2+32= 35.

-20 + 55 = (-20) + (+55) = + 35— Сначала получим ДК отрицательного числа (-20).

begin</p><p> _< >0 0 0 gets ПК\ 1 getstext\ _1 1 1 getstext\ \ cline textto 1 1 0 getstext\ end

После этого произведем вычисления:

text<перенос из знакового разряда (отбрасывается)></p><p>\ begin downarrow \ fbox 1 1 getsперенос\ _ 1 1 0 = -20\ 1 0 1 = +55\ cline 1 0 1 getsрезультат\ \ end\ text

Получено положительное число, поэтому ДК=ПК, для проверки результата нужно только перевести значащие разряды в десятичный код: 100011_<2>=1+2+32= 35.

-20 - 55 = (-20) + (-55) = - 75 — Сначала получим дополнительный код отрицательных чисел. Для числа (-20)он получается следующим образом:

text<резервный разряд во избежание переполнения></p><p>\ begin downarrow 0 0 0 getstext\ fbox<phantom> 1 _ 1 1 1 getstext\ fbox<phantom> 1 1. 1 1 0 getstext\ end

(-55)

А для числа —

text<резервный разряд во избежание переполнения></p><p>\ begin downarrow 1 0 1 gets ПК\ fbox 0 0 0 phantom> 1 1. 0 1 0 gets ДК\ end

Сложим полученные числа в том же формате:

begin</p><p> begin text to 1 gets перенос\ 1. 1 1 0 =-20\ 1. 0 1 0 =-55\ cline 1. 1 0 0 gets результат\ uparrow \ end\ text end

ДКneПК

Поскольку число отрицательное, . Для проверки значащих разрядов числа нужно сначала вычислить обратный код , после чего перевести его в прямой код инверсией —

begin</p><p> _0 1 1 1 \ 0 1 1 0 0 1 1 gets ПК.\ end\

1001011_<2></p><p>И только после этого полученное число проверяется переводом в десятичный код по (11.2): =1+2+8+64= 75.

Оцените статью
TutShema
Добавить комментарий