8 Сложение и вычитание в обратном и дополнительном кодах

 

Введение обратного и дополнительного кода позволило избавиться от операции вычитания. С использованием этих кодов операция вычитания сводится к операции сложения уменьшаемого и вычитаемого, причем вычитание представлено в обратном или дополнительном коде. Другими словами, операция D=A-B сводится к операции D=A+(-B), где B должно быть записано в обратном или дополнительном коде. Это достаточно сильный ход, позволяющий всю двоичную арифметику свести к сложению и сдвигам. Если Вы вернетесь к рассмотренным выше разделам, то вспомните, что умножение и деление было реализовано через сложение, сдвиги и вычитание.

Далее разделы будут содержать в заголовках слова «сложение и вычитание», но Вы уже понимаете, что на самом деле речь будет идти только о сложении

 

8.1 Сложение и вычитание в двоичном дополнительном коде

Суммирование ведется как обычно в двоичной системе, включая знаковые разряды, возможный перенос из старшего разряда отбрасывается. Правильный результат получится, если значение суммы не выходит за пределы диапазона представления чисел с заданной разрядностью для дополнительного кода. Как Вы помните, этот диапазон Вы ранее нашли самостоятельно :-). Если же сумма выходит за пределы этого диапазона, то говорят, что возникает переполнение (OVR - overflow).

Примеры:

 

4 – 9 = 4 + (-9) -5-6=(-5)+(-6)

[+4]Доп=0,0100 [+5]Доп=0,0101

[+9]Доп=0,1001 [+6]Доп=0,0110

[ -9]Доп=1,0111 [ -5]Доп=1,1011

[ -6]Доп=1,1010

         
   

+0,0100 +1,1011

1,0111 1,1010

1,1011 1,0101

 

Во втором примере перенос из знакового разряда (он изображен длинной стрелкой) в соответствии с правилом игнорируется.

Возникает вопрос – а как проверить правильность вычислений? Нужно контролировать два параметра – правильность знака и значение величинной части. По знакам вроде все нормально – результат и в первом примере и во втором примере должен получиться отрицательным, мы и имеем в знаковых разрядах по единице. А вот величинную часть «на глазок» оценить трудно (вот бы где пригодился прямой код, но в нем не так удобно производить вычисления).

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

 

1,1011→0,0101B=+510 1,0101→0,1011=+1110.

 

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

 

8.2 Сложение и вычитание в двоичном обратном коде

Суммирование ведется как обычно в двоичной системе, включая знаковые разряды, возможный перенос из старшего разряда циклически прибавляется к младшему значащему разряду суммы. Правильный результат получится, если значение суммы не выходит за пределы диапазона представления чисел с заданной разрядностью для обратного кода. :-). Если же сумма выходит за пределы этого диапазона, то говорят, что возникает переполнение (OVR - OVeRflow). Операции в обратном двоичном коде применяются гораздо реже, но для обучения это очень полезная вещь.

Рассмотрим примеры.

 

4 – 9 = 4 + (-9) -5-6=(-5)+(-6)

[+4]Обр=0,0100 [+5]Обр=0,0101

[+9]Обр=0,1001 [+6]Обр=0,0110

[ -9]Обр=1,0110 [ -5]Обр=1,1010

[ -6]Обр=1,1001

     
 

+0,0100 +1,1010

1,0110 1,1001

1,1010 + 1,0011

1

1,0100

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

 

1,1010→0,0101B=+510 1,0100→0,1011=+1110.

 

Как видно, результат получен правильно.

8.3 Переполнение в двоичном дополнительном и обратном кодах

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

 

10+10=20 (-10)+(-10)=(-20)

[+10]Доп=0,1010 [+10]Доп=0,1010

[ -10]Доп=1,0110

             
   

+0,1010 +1,0110

0,1010 1,0110

1,0100 10,1100

 

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

 

 
«если есть перенос только в знаковый разряд или перенос только из знакового разряда, то это – признак переполнения»

 

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

А что нужно делать, если возникло переполнение? А нужно вернуться к исходным положительным числам, увеличить их разрядность и вновь выполнить действия. Нам в примерах обычно достаточно увеличить разрядность на один разряд, а микропроцессорам (а, точнее, программистам) приходится увеличивать разрядность числа на одно слово. Это в свою очередь приводит к увеличению занимаемого объема памяти, снижению быстродействия и т.д., поэтому заранее никто не берет разрядность с «запасом». А вот если микропроцессор скажет, что есть OVR, то в этом случае и нужно увеличить разрядность чисел.

Давайте последуем этому совету и переделаем последние примеры.

 

10+10=20 (-10)+(-10)=(-20)

[+10]Доп=0,01010 [+10]Доп=0,01010

[ -10]Доп=1,10110

             
 

+0,01010 +1,10110

0,01010 1,10110

0,10100 1,01100

 

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

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

 

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

 

Однако первый опыт чтения лекций с учетом вышеприведенного текста показал, что времени на «живых» лекциях все равно не хватает, поэтому тяжелый труд был продолжен…

 

9 Основные понятия алгебры логики

 

Математической основой цифровой техники служит булева алгебра (Boolean algebra), иногда называемая также алгеброй логики и предложенная в 1854 году Джорджем Булем. (1815 – 1864) для анализа человеческих рассуждений. По-другому булеву алгебру называют «исчисление высказываний», и оно входит в начальный раздел математической логики. Кстати, родился Джордж Буль 2 ноября 1815 года, а в этот же день, 2 ноября, но 1902 года, родился Сергей Алексеевич Лебедев – академик, Герой социалистического труда, лауреат Ленинской и Государственной премий, основоположник советской вычислительной техники, разработчик легендарного компьютера БЭСМ-6.

Дать определение основам булевой алгебры можно по-разному. Вот, например, как это делается в японских университетах [4]:

«Булева алгебра может быть определена как алгебраическая система, удовлетворяющая следующим постулатам.

Определение. Если для множества В = {a,b,c,…} и двух типов операторов + и · (логическая сумма и логическое произведение) справедливы четыре следующие соотношения, то такая система называется булевой алгеброй:

1) a+b=b+a, a·b=b·a для любых a,bÎB (коммутативность);

2) a+(b·c)=(a+b) (a+c), a·(b+c)=(a·b)+(a·c) для любых a,bÎB (дистрибутивность);

3) найдутся 1ÎB и 0 ÎB, такие, что a+0=a, a·1=a для любого aÎB (единичные элементы);

4) найдется такой, что , для любого aÎB (дополнение).»

И это все!

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

В общем случае общая математическая система определяется множеством элементов, множеством операций и множеством постулатов.

Множество элементов

В булевой алгебре существует 2 (всего два!) элемента, которые иногда называют ее константами и обозначают 0 и 1, для отличия от цифр их называют «логический 0» и «логическая 1». Считается обычно, что 1 соответствует выполнению какого-либо условия, высказывания или соответствует состоянию «истина» («truth»), а логический 0 – невыполнению условия, высказывания, состоянию «ложь» («false»). В качестве состояний «истина» и «ложь» могут быть использованы и уровни напряжения.

Говорят, что булевы переменные удовлетворяют условию «исключенного третьего», т.е.

x = 0 если х ≠ 1,

x = 1 если х ≠ 0,

в общем, или 0, или 1 – третьего не дано.

Состояния «истина» и «ложь» могут быть представлены в виде электромеханического (электрического) аналога (рисунок 9.1).