Как и большинство объяснений, которые я видел, приведенные выше ясно показывают, как работать с дополнением 2, но на самом деле не объясняют, что это такое математически. Я постараюсь сделать это, по крайней мере, для целых чисел, и расскажу о некоторой предыстории, которая, вероятно, будет знакома первой.
Вспомните, как работает десятичное число:
2345
- это способ записи
2 × 10 3 + 3 × 10 2 + 4 × 10 1 + 5 × 10 0 .
Таким же образом, двоичный код - это способ записи чисел, использующий только 0 и 1, следуя той же общей идее, но заменяя те 10, которые указаны выше, на 2. Затем в двоичном коде
1111
является способом записи
1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0,
и если вы решите это, получится равным 15 (основание 10). Это потому что
8 + 4 + 2 + 1 = 15.
Это все хорошо и хорошо для положительных чисел. Это даже работает для отрицательных чисел, если вы хотите просто поставить знак минус перед ними, как люди делают с десятичными числами. Это даже можно сделать с помощью компьютеров, но я не видел такого компьютера с начала 1970-х годов. Я оставлю причины для другого обсуждения.
Для компьютеров оказывается более эффективным использовать дополнение для отрицательных чисел. И вот кое-что, что часто упускается из виду. Обозначения дополнения включают в себя некоторый вид обращения цифр числа, даже подразумеваемых нулей, которые предшествуют нормальному положительному числу. Это неловко, потому что возникает вопрос: все они? Это может быть бесконечное количество цифр для рассмотрения.
К счастью, компьютеры не представляют бесконечности. Числа ограничены определенной длиной (или шириной, если вы предпочитаете). Итак, давайте вернемся к положительным двоичным числам, но с определенным размером. Я буду использовать 8 цифр («бит») для этих примеров. Таким образом, наше двоичное число будет действительно
00001111
или
0 × 2 7 + 0 × 2 6 + 0 × 2 5 + 0 × 2 4 + 1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0
Чтобы сформировать отрицание дополнения 2, мы сначала добавляем все (двоичные) цифры в форму
11110000
и добавляем 1 к форме
11110001
но как нам понять, что это означает -15?
Ответ в том, что мы меняем значение старшего бита (самого левого). Этот бит будет 1 для всех отрицательных чисел. Изменение будет состоять в том, чтобы изменить знак своего вклада в значение числа, в котором он появляется. Итак, теперь наш 11110001, как предполагается , представляет
- 1 × 2 7 + 1 × 2 6 + 1 × 2 5 + 1 × 2 4 + 0 × 2 3 + 0 × 2 2 + 0 × 2 1 + 1 × 2 0
Заметьте, что "-" перед этим выражением? Это означает, что знаковый бит имеет вес -2 7 , то есть -128 (основание 10). Все остальные позиции сохраняют тот же вес, что и в двоичных числах без знака.
Выработка нашего -15, это
-128 + 64 + 32 + 16 + 1
Попробуйте на своем калькуляторе. это -15.
Из трех основных способов, с помощью которых я видел отрицательные числа, представленные в компьютерах, дополнение 2 выигрывает для удобства в общем использовании. Это странно, хотя. Поскольку это двоичный код, должно быть четное количество возможных битовых комбинаций. Каждое положительное число может быть соединено с его отрицательным, но есть только один ноль. Отрицание нуля дает вам ноль. Так что есть еще одна комбинация, число с 1 в знаковый бит и 0 везде. Соответствующее положительное число не будет соответствовать количеству используемых битов.
Что еще более странно в этом числе, так это то, что если вы попытаетесь сформировать его положительное число, дополнив и добавив одно, вы получите то же отрицательное число обратно. Кажется естественным, что ноль сделал бы это, но это неожиданное и совсем не то поведение, к которому мы привыкли, поскольку помимо компьютеров мы обычно думаем о неограниченном количестве цифр, а не об этой арифметике фиксированной длины.
Это как верхушка айсберга странностей. Под поверхностью еще больше подстерегает, но этого достаточно для обсуждения. Возможно, вы найдете больше, если исследуете «переполнение» для арифметики с фиксированной точкой. Если вы действительно хотите войти в это, вы можете также исследовать «модульную арифметику».