Существует ли математическая формула для умножения комплемента двух при работе с переполнением? - PullRequest
0 голосов
/ 08 апреля 2020

Например, учитывая размер слова в 4 бита:

0b1001 * 0b0111 = 0b1111 // -7 * 7 = -1
0b0111 * 0b0111 = 0b0001 // 7 * 7 = 1
0b0111 * 0b0110 = 0b1010 // 7 * 6 = -6
0b1001 * 0b0110 = 0b0110 // -7 * 6 = 6

Несомненно, здесь происходит некоторая модульная арифметика c, но способ, которым вы берете мод, кажется весьма противоречивым. Есть ли аккуратная математическая формулировка умножения комплемента на два?

1 Ответ

0 голосов
/ 08 апреля 2020

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

В терминах модульной арифметики c операции также означают одно и то же. С 4-битными словами, когда вы говорите:

r = a * b;

Вы получаете r = a * b mod 16.

Единственная разница между знаком и без знака - это значение, которое мы присваиваем в наших головах остатки мод 16. Если мы думаем о словах как без знака, то у нас есть значения 0-15. Но 15 = -1 mod 16, 14 = -2 mod 16, et c, и если мы думаем о словах как о знаковых, то мы просто думаем о значениях от -8 до 7 вместо 0 до 15.

Оператор напоминания %, который вы получаете в C, java и т. Д. c, раздражает то, как он обрабатывает отрицательные числа. Если вы хотите express ваше 4-битное умножение, используя этот оператор в более крупных словах, то вы можете сказать:

a * b =  ( (a * b % 16) + 24 ) % 16 - 8

Если оператор остатка работал «правильно», так что -1% 16 == 15 тогда вы могли бы написать a * b = (a * b + 8) % 16 - 8

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