приведем пример:
у нас есть два числа в двух байтах в двоичном виде:
A = 10010111
B = 00100110
(обратите внимание, что машина не знает понятия подписанного или неподписанного на этом уровне)
теперь, когда вы говорите "добавить" эти два, что означает машина? он просто добавляет:
R = 10111101 (и бит переноса: 1)
Теперь мы, как компилятор, должны интерпретировать операцию. у нас есть два варианта: числа могут быть подписаны или без знака.
1- беззнаковый случай: в c числа имеют тип "unsigned char", значения 151 и 38, а результат 189. Это тривиально.
2 - случай со знаком: мы, компилятор, интерпретируем числа в соответствии с их msb, и первое число равно -105, а второе - 38. Поэтому -105 + 38 = -67. Но -67 - это 10111101. Но это то, что мы уже имеем в результате (R)! Результат тот же, разница только в том, как его интерпретирует компилятор.
Вывод состоит в том, что независимо от того, как мы рассматриваем числа, машина выполняет одну и ту же операцию над числами. Но компилятор будет интерпретировать результаты в свою очередь.
Обратите внимание, что это не машина, которая знает концепцию дополнения 2 . он просто добавляет два числа, не заботясь о содержании. Компилятор затем просматривает бит знака и решает .
Когда дело доходит до вычитания, на этот раз операция уникальна: возьмите 2-е дополнение второго числа и добавьте два.