Очевидно, математически, | & minus; 2 31 | составляет 2 31 . Если у нас есть 32 бита для представления целых чисел, мы можем представить не более 2 32 чисел. Если нам нужно представление, симметричное относительно 0, нам нужно принять несколько решений.
Для следующего, как и в вашем вопросе, я предполагаю 32-битные числа. По крайней мере, один битовый шаблон должен быть использован для 0. Таким образом, мы получим 2 32 & plusmn; 1 или менее битовых шаблонов для остальных чисел. Это число нечетное, поэтому мы можем либо иметь представление, которое не совсем симметрично относительно нуля, либо иметь одно число с двумя разными представлениями.
- Если мы используем представление знак-величина , старший значащий бит представляет знак числа, а остальные биты представляют величину числа. В этой схеме
0x80000000
- это «отрицательный ноль» (то есть ноль), а 0x00000000
- это «положительный ноль» или обычный ноль. В этой схеме самое положительное число - 0x7fffffff
(2147483647), а самое отрицательное число - 0xffffffff
(& минус; 2147483647). Эта схема имеет то преимущество, что нам легко «декодировать», и она симметрична. Эта схема имеет недостаток, заключающийся в том, что вычисление a + b
, когда a
и b
имеют разные знаки, является особым случаем и требует особого внимания.
- Если мы используем представление добавок , самый значимый бит по-прежнему представляет знак. Положительные числа имеют этот бит как 0, а остальные биты составляют величину числа. Для отрицательных чисел вы просто инвертируете биты из соответствующего представления положительного числа (возьмите дополнение с длинной серией единиц - отсюда и имя ones ', дополнение ). В этой схеме максимальное положительное число все еще равно
0x7fffffff
(2147483647), а максимальное отрицательное число равно 0x80000000
(& минус; 2147483647). Снова есть два представления 0: положительный ноль равен 0x00000000
, а отрицательный ноль равен 0xffffffff
. Эта схема также имеет проблемы с расчетами с использованием отрицательных чисел.
- Если мы используем схему дополнения до двух , отрицательные числа получаются путем взятия представления дополнения и добавления к нему
1
. В этой схеме есть только один 0, а именно 0x00000000
. Наиболее положительное число - 0x7fffffff
(2147483647), а наиболее отрицательное число - 0x80000000
(& минус; 2147483648). В этом представлении есть асимметрия. Преимущество этой схемы в том, что не нужно иметь дело с особыми случаями для отрицательного числа. Представление заботится о том, чтобы дать вам правильный ответ, если результат не переполняется. По этой причине большая часть текущего оборудования представляет целые числа в этом представлении.
В представлении дополнения до двух невозможно представить 2 31 . Фактически, если вы посмотрите на limits.h
вашего компилятора или эквивалентный файл, вы можете увидеть определение для INT_MIN
таким образом:
#define INT_MIN (-2147483647 - 1)
Это сделано, а не
#define INT_MIN -2147483648
потому что 2147483648 слишком велик, чтобы поместиться в int
в 32-битном представлении дополнения до двух. К тому времени, когда унарный оператор минус «получает» номер для работы, уже слишком поздно: переполнение уже произошло, и вы не можете это исправить.
Итак, чтобы ответить на ваш исходный вопрос, абсолютное значение наиболее отрицательного числа в представлении дополнения до двух не может быть представлено в этой кодировке. Кроме того, из вышесказанного, чтобы перейти от отрицательного значения к положительному значению в представлении дополнения до двух, вы берете его дополнение и затем добавляете 1. Итак, для 0x80000000
:
1000 0000 0000 0000 0000 0000 0000 0000 original number
0111 1111 1111 1111 1111 1111 1111 1111 ones' complement
1000 0000 0000 0000 0000 0000 0000 0000 + 1
вы получите исходный номер обратно.