В подписанном int или в двоичной цифре

Ноль считается положительным знаком

а также

1 рассматривается как отрицательный знак.

Например :-

1000 0000 0000 0110 = -6 
0000 0000 0000 0110 =  6

Но в форме импульса 1 считается положительным, а 0 - нейтральным.

         ---   ---   ---
         | |   | |   | |
---------   ---   ---   ---------

Зачем? Есть ли за этим логика.

И можно ли трактовать это противоположным образом, то есть 1 как положительный знак и 0 как отрицательный знак

3 ответа3

9

Ваше первоначальное утверждение не совсем верно, не для подавляющего большинства архитектур ЦП, которые имеют что-либо похожее на общее использование - которые используют «арифметику дополнения двух».

В арифметике дополнения 2, если бит старшего разряда равен 1, это указывает на отрицательное число; но если старший бит равен 0, это не означает положительное число. Это указывает на неотрицательные. Разница тонкая, но важная. Число может быть нулевым или положительным.

В дополнении 2 шкала чисел выглядит следующим образом - я буду использовать восьмибитные целые числа для простоты:

binary   signed  unsigned
01111111  127      127
01111110  126      126
 ...
00000011    3        3
00000010    2        2
00000001    1        1
00000000    0        0
11111111   -1      255
11111110   -2      254
 ...
10000010 -126      130
10000001 -127      129
10000000 -128      128

Чтобы аннулировать (арифметически инвертировать) число в этой системе, т.е. умножить его на -1: сначала нужно инвертировать все биты, а затем добавить 1. Так что, если бы мы начали с 1 и инвертировали биты, мы получили бы 11111110. Добавьте 1, и мы получим 11111111. Как указано выше. Обратите внимание, что если мы сделаем это снова, мы вернемся к 00000001, как мы должны.

Компьютеры используют эту систему, потому что она делает сложную, вычитаемую и т.д. Арифметическую логику очень простой: та же логика (простые двоичные сумматоры; вы просто добавляете все биты, включая биты знака) работает как для чисел со знаком, так и для чисел без знака. Обратите внимание, что добавление 1 к любому числу на этой шкале возвращает вас к правильному ответу ... за исключением случаев переполнения: добавление от 1 до 127 приводит к -128, если вы интерпретируете числа как подписанные. Но переполнения, переносы и т.д. Обычно фиксируются либо флагами условий, либо исключениями.

Любопытно, что у нас есть еще два отрицательных числа, у нас есть еще одно отрицательное число, чем у нас положительное. Ноль не является ни отрицательным, ни положительным. Таким образом, с восемью битами со знаком мы можем представить -128, но не +128. +127 - самое высокое положительное число. Это не большая проблема.

Было построено несколько исторических компьютеров (серии CDC 3000 и 6000 и некоторые старые мэйнфреймы Univac; я не знаю современных примеров), которые использовали «дополнение». В дополнение к этому, чтобы инвертировать число, вы просто переворачиваете биты. Это приводит к почти тому же масштабу, что и выше, за исключением того, что отрицательная сторона изменяется от -127 до ... -0! Это верно, в своей компании. машины, у вас есть два нуля: положительный ноль и отрицательный ноль. Это делает арифметику в целом более сложной. Отрицательные нули обычно преобразуются в положительные в некоторой точке.

Вы, вероятно, думаете, что это должно быть больше похоже на "звездную величину", что аналогично тому, как мы обычно пишем числа. например, -2 будет 10000002. Вы заметите, что добавление 1 к этому не даст вам правильное представление величины со знаком для -1. Это дает вам -3 вместо. Это усложняет выполнение арифметики, поэтому она не используется.

4

Это на самом деле довольно сложно. На одном уровне ответ таков: «потому что нам нужен какой-то стандарт»: если вы создаете новую систему, гораздо проще сделать ее так же, как работают старые системы, чтобы вам было легче взаимодействовать с этими старыми системами. Однако в некоторых из этих случаев есть более глубокие причины.

В этом посте я приму восьмибитные целые числа. Принципы должны работать одинаково при использовании разного количества битов.

Электрические импульсы

Здесь, только с двумя значениями, не имеет значения, что мы называем «ноль» и что мы называем «один». На самом деле, нет причин называть их «ноль» и «один». Например, 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 , что является отрицательным.

Это может показаться странным способом представления целых чисел со знаком, но у него есть ряд преимуществ по сравнению с более очевидной величиной со знаком. Во-первых, это избавляет от проблемы, о которой я упоминал ранее, с двумя представлениями для нуля. С другой стороны, вы можете просто добавить числа, используя ту же схему, что и для добавления чисел без знака, и все будет работать правильно, если нет переполнения (и даже если переполнение будет проще для обработки). Это не правда со звездной величиной.

Заключение

Существует несколько возможных способов представления чисел со знаком ; Величина со знаком и дополнение к двум - только два из самых популярных. В каком-то смысле не имеет значения, какой вы используете; Вы можете теоретически изобрести свой собственный метод, которого нет в этом списке (или просто использовать величину со знаком с обратным битом знака) и создать целые компьютеры, которые его используют. Это, скорее всего, не будет хорошей идеей, потому что вам придется конвертировать в другой формат, если вы хотите поделиться данными с другим компьютером. Мы могли бы использовать целые числа со знаком в качестве нашего стандарта (как мы делали для чисел с плавающей запятой), и тогда лучшим выбором для большинства новых компьютеров, вероятно, было бы то же самое. Тем не менее, выбор был не совсем произвольным, и есть веские причины, чтобы заставить положительные целые числа использовать начальный ноль вместо начального (например, соответствие беззнаковым числам).

0

Это произвольный стандарт для целых чисел. Посмотрите на меньший байт со знаком, где от 00000000 до 01111111 обрабатываются как положительные целые числа, а старший бит, если установлен, делает их отрицательными, охватывая диапазон от -127 до 127 (основание 10), при этом ноль кодируется либо с установленным начальным битом или нет. Идентичные битовые комбинации также кодируют числа без знака от 0 до 255, так что это просто стандарт, позволяющий программистам понимать работу других. См. Http://en.wikipedia.org/wiki/Signed_number_representations для получения информации о представлении чисел со знаком.

Вы можете изобрести свой собственный стандарт для чисел со знаком, но это может привести к путанице. В некоторых языках Boolean True рассматривается как 00000001, в других языках (например, VB) это 10000001, а в других - любое значение, отличное от нуля. Это еще одна ловушка, с которой следует опасаться при переводе языков программ.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .