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

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

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

а также

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

Например:-

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

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

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

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

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

3 ответа

Решение

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

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

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

бинарный подписанный без знака
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 вместо. Это усложняет выполнение арифметики, поэтому она не используется.

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

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

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

Здесь, только с двумя значениями, не имеет значения, что мы называем "ноль" и что мы называем "один". На самом деле нет никаких оснований называть их "ноль" и "один". Например, USB использует "J" и "K", а некоторые USB-устройства используют противоположное соглашение, как и другие, для фактической передачи сигнала.

Целочисленное кодирование

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

Однако не все номера подписаны. Если я кодирую количество виджетов, созданных моей фабрикой сегодня, я хочу использовать число без знака (если я иногда не уничтожаю виджеты на своей фабрике). В этом случае было бы разумно 0000 0110 значит, я сделал шесть виджетов в тот день.

Если вы используете как подписанные, так и беззнаковые числа, было бы неплохо, если бы преобразование между ними было максимально простым. Проще конвертировать, если одни и те же биты представляют одно и то же число в обоих случаях, поэтому мы хотим 0000 0110 означать шесть, даже если мы используем целое число со знаком. Это приводит к созданию ведущих 1 быть отрицательным и ведущим 0 быть положительным.

Два дополнения

Однако очень немногие системы на самом деле используют знаковые величины для целых чисел. Величина со знаком имеет ряд проблем, включая как 0000 0000 а также 1000 0000 это означает то же самое (ноль). Вместо этого большинство представляет целые числа со знаком, используя то, что называется "дополнением до двух". Он представляет положительные числа таким же образом (с начальным нулем, а остальные биты как с беззнаковыми числами), но отрицательные числа представляет по-разному. В случае 8-разрядных чисел без знака наиболее значимым является разряд 128; с двумя дополнительными восьмибитными числами это отрицательное 128-е место. Таким образом, 1000 0000 отрицательно 128, 1000 0001 is negative 128 + 1 = negative 127, all the way up to 1111 1111, which is negative one.

This may seem like an odd way of representing signed integers, but it has a number of advantages over the more obvious signed-magnitude. For one thing, it gets rid of the problem I mentioned earlier of having two representations for zero. For another, you can just add the numbers using the same circuitry used for adding unsigned numbers, and it will work out correctly assuming there's no overflow (and even if there is overflow, it's easier to handle). That isn't true with signed magnitude.

Заключение

There are a number of possible ways to represent signed numbers; signed magnitude and two's complement are just two of the more popular ones. In one sense, it doesn't matter which you use; you could theoretically invent your own method not listed there (or just use signed magnitude with the sign bit reversed) and make entire computers that use it. That would very likely not be a good idea though, because you'd need to convert to a different format if you wanted to share data with another computer. We could have ended up using signed-magnitude integers as our standard (as we did for floating point numbers), and then the best choice for most new computers would probably be to do the same thing. However, the choice wasn't exactly arbitrary, and there are good reasons to make positive integers use a leading zero instead of a leading one (such as conformance with unsigned numbers).

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

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

Другие вопросы по тегам