Это на самом деле довольно сложно. На одном уровне ответ таков: «потому что нам нужен какой-то стандарт»: если вы создаете новую систему, гораздо проще сделать ее так же, как работают старые системы, чтобы вам было легче взаимодействовать с этими старыми системами. Однако в некоторых из этих случаев есть более глубокие причины.
В этом посте я приму восьмибитные целые числа. Принципы должны работать одинаково при использовании разного количества битов.
Электрические импульсы
Здесь, только с двумя значениями, не имеет значения, что мы называем «ноль» и что мы называем «один». На самом деле, нет причин называть их «ноль» и «один». Например, USB использует «J» и «K», а некоторые USB-устройства используют противоположное соглашение, как и другие, для фактической передачи сигнала.
Целочисленное кодирование
Существует несколько способов кодирования целых чисел. Тот, который вы показываете в своем вопросе, называется «звездной величиной». Это очень похоже на то, как мы пишем числа в повседневной жизни: у нас потенциально есть знак минус, а затем мы пишем число. В этом случае знак минус (или знак плюс) - это просто значение первого бита.
Однако не все номера подписаны. Если я кодирую количество виджетов, созданных моей фабрикой сегодня, я хочу использовать число без знака (если я иногда не уничтожаю виджеты на своей фабрике). В этом случае было бы разумно позволить 0000 0110
означать, что я сделал шесть виджетов в тот день.
Если вы используете как подписанные, так и беззнаковые числа, было бы неплохо, если бы преобразование между ними было максимально простым. Проще конвертировать, если одни и те же биты представляют одно и то же число в обоих случаях, поэтому мы хотим, чтобы 0000 0110
означало шесть, даже если мы используем целое число со знаком. Это приводит к тому, что ведущий 1
будет отрицательным, а ведущий 0
- положительным.
Два дополнения
Однако в настоящее время очень немногие системы используют знаковые величины для целых чисел. Величина со знаком имеет ряд проблем, включая и 0000 0000
и 1000 0000
означает одно и то же (ноль). Вместо этого большинство представляет целые числа со знаком, используя то, что называется «дополнением до двух». Он представляет положительные числа таким же образом (с начальным нулем, а остальные биты как с беззнаковыми числами), но отрицательные числа представляет по-разному. В случае 8-разрядных чисел без знака наиболее значимым является разряд 128; с двумя дополнительными восьмибитными числами это отрицательное 128-е место. Таким образом, 1000 0000
является отрицательным 128, 1000 0001
является отрицательным 128 + 1 = отрицательным 127, вплоть до 1111 1111
, что является отрицательным.
Это может показаться странным способом представления целых чисел со знаком, но у него есть ряд преимуществ по сравнению с более очевидной величиной со знаком. Во-первых, это избавляет от проблемы, о которой я упоминал ранее, с двумя представлениями для нуля. С другой стороны, вы можете просто добавить числа, используя ту же схему, что и для добавления чисел без знака, и все будет работать правильно, если нет переполнения (и даже если переполнение будет проще для обработки). Это не правда со звездной величиной.
Заключение
Существует несколько возможных способов представления чисел со знаком ; Величина со знаком и дополнение к двум - только два из самых популярных. В каком-то смысле не имеет значения, какой вы используете; Вы можете теоретически изобрести свой собственный метод, которого нет в этом списке (или просто использовать величину со знаком с обратным битом знака) и создать целые компьютеры, которые его используют. Это, скорее всего, не будет хорошей идеей, потому что вам придется конвертировать в другой формат, если вы хотите поделиться данными с другим компьютером. Мы могли бы использовать целые числа со знаком в качестве нашего стандарта (как мы делали для чисел с плавающей запятой), и тогда лучшим выбором для большинства новых компьютеров, вероятно, было бы то же самое. Тем не менее, выбор был не совсем произвольным, и есть веские причины, чтобы заставить положительные целые числа использовать начальный ноль вместо начального (например, соответствие беззнаковым числам).