5 Сложение и вычитание в произвольной системе счисления
Как следует из вышеприведенного материала, все действия арифметики могут быть сведены к сложению и вычитанию. Попробуем на основе имеющегося опыта сформулировать общие правила, пригодные для любой системы счисления.
Для выполнения операции сложения следует поразрядно, начиная с младшего разряда, складывать слагаемые. Если в результате сложения в разряде возникнет сумма, превышающая максимальную цифру системы счисления, нужно из полученной суммы вычесть основание системы счисления (а может быть, и несколько основания, если складывается несколько чисел), результат записать в данный разряд и осуществить перенос в старший разряд (или столько переносов, сколько раз вычиталось основание системы счисления). Этот перенос(ы) следует прибавить к содержимому старшего разряда.
Проверьте этот алгоритм на десятичной и двоичной системах счисления и придумайте примеры для восьмеричной и шестнадцатеричной систем счисления.
Для выполнения вычитания нужно поразрядно, начиная с младшего разряда, производить вычитание вычитаемого из уменьшаемого. Если в данном разряде уменьшаемое меньше вычитаемого, нужно взять заем из старшего (старших) разряда. Заем «приносит» в разряд число, равное основанию системы счисления, и вычитать нужно из суммы уменьшаемого и основания системы счисления.
Далее смотри на один абзац выше.
6 Сложение и вычитание в коде BCD
Поскольку 8-4-2-1 это код, а не система счисления, полностью применить правила сложения и вычитания для произвольных систем счисления просто так не получится. Основой сложения и вычитания в двоично-десятичном натуральном коде является двоичная арифметика, однако есть некоторые тонкости, которые мы сейчас выявим. Рассмотрим три простых примера.
+0000|_|1000
0000|_|0111
0000| _|1111
С точки зрения двоичной арифметики всё безупречно. Но кто действительно понял, что такое код BCD, сразу же скажет, что здесь присутствует ……………. (подставьте пропущенное слово). Откуда она появилась? Дело в том, что мы имеем дело не с чисто двоичной системой счисления, ни с чисто десятичной, а с их гибридом. Действия выполняются в двоичной арифметике, но использоваться должны десятичные цифры, и, следовательно, аналогом основания системы счисления является число десять, а роль разряда играет тетрада. Как выше говорилось, если в разряде (тетраде) возникает число, большее, чем максимальная цифра (это девять для десятичной системы счисления), то из данного разряда нужно вычесть основание системы счисления и перенести единицу в старший разряд. Но в коде BCD перенос в старший разряд (старшую тетраду) произойдет, если в данной тетраде наберется число большее, чем 1111B (0Fh). Поэтому нужно кому-то (студенту или микропроцессору) отслеживать такие ситуации и корректировать их. В книжках это коротко описывается следующей фразой: «В случае возникновения в результате сложения псевдотетрады ее нужно скорректировать прибавлением двоичного числа шесть». Кто-то, наверное, уже понял суть этой фразы, и сможет ее объяснить на экзамене, но для получения удовлетворительной оценки можно ее просто выучить.
Ну и давайте, применим это правило к примеру.
+0000|_|1000
0000|_|0111
+0000|_|1111 – есть псевдотетрада
0110 - корректируем
0001|_|0101 – получаем правильный результат
Рассмотрим следующий простой пример.
![]() |
+0000|_|1001
0000|_|0111
0001|_|0000 – нет псевдотетрады
Здесь тоже все замечательно с точки зрения двоичной арифметики, но совсем не получается по десятичной арифметике, ведь не может же быть, чтобы 9 + 7 = 10? Опуская подробный анализ, аналогичный проведенному выше (Вы и сами можете это сделать), приведем правило: «Если в результате сложения чисел в коде BCD возникает перенос в старшую тетраду, к той тетраде, из которой был перенос, нужно прибавить двоичное число 0110».
Опять просто применим это правило:
![]() |
+0000|_|1001
0000|_|0111
0001|_|0000 – был перенос в старшую тетраду
0110 - корректируем
0001|_|0110 – имеем правильный результат
Ну, и последний пример.
![]() |
-0001|_|0000
0000|_|1001
+0000|_|0111
С точки зрения двоичной системы счисления снова все хорошо. Вы уже догадались, что нужно самим подумать, и прийти к следующему выводу: «Если при вычитании в коде BCD возникает заем, то из тетрады, в которую был заем нужно вычесть двоичное число 0110». Применяем:
![]() |
-0001|_|0000
0000|_|1001
-0000|_|0111 – в эту тетраду был заем
0110 – корректируем за счет вычитания
0000|_|0001 – получили правильный результат
Ну, вот и все пока… Осталось все это тщательно вызубрить, решить N примеров и Вы готовы к тому, чтобы попытаться выполнить домашнюю работу и контрольную работу в классе по второму модулю.
А если Вы еще и поняли, о чем здесь речь, то Вам не составит труда понять, что делает команда DAA (Decimal Accumulator Adjustment) в микропроцессорах I80x86.