Почему этот код печатает два отрицательных числа?

int a = Integer.MIN_VALUE;
int b = -a;
System.out.println("a = "+a + " | b = "+b);

Результат:

a = -2147483648 | b = -2147483648

Я ожидал, что b будет положительным числом.

Ответы

Ответ 1

Изменение знака Integer.MIN_VALUE вызывает переполнение; вы видите результат этого.

Ответ 2

Если вы когда-либо делали что-то вроде этого:

int a = Integer.MAX_VALUE;
a++;
System.out.println(a);

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

То же самое происходит и здесь.

Отрицание минимального значения int математически дало бы нам 2147483648, но так как это больше, чем максимальное значение. Он снова возвращается к минимальному значению, которое равно -2147483648.

Забавный факт: отрицание в основном переключает каждый бит от 0 до 1 и от 1 до 0, а затем добавляет один. Попробуйте сделать это до 10000000000000000000000000000000, что и есть значение int min в двоичном формате.

Ответ 3

Для базового двоичного объяснения это связано с тем, что подписанные целые числа хранятся с Два дополнения.

Итак, самое отрицательное число в двоичном формате - 1000 0000. Чтобы инвертировать знак, вы переворачиваете все биты и добавляете их так.

1000 0000 = > 0111 1111 + 1 = 1000 0000

И вы вернулись туда, где вы начали!

Как и в приведенном выше примере, подписанный диапазон байта (8 бит) составляет от -128 до 127, поэтому - (- 128) равно 128, что на 1 более 127, поэтому оно переполняется до -128.

А зачем использовать два дополнения? 1 - 1 становится равным 1 + (-1) или 0001 + 1111 = 0000. Таким образом, сохраняя отрицательные числа в двух дополнениях, вычитание выполняется просто берет два дополнения второго номера и просто добавляя их вместе. (Что намного более эффективно для машины, чем добавление схемы вычитания в Арифметико-логический блок (ALU), поскольку он уже побито не добавляет и дополняет дополнение к двум).

Ответ 4

Обычно, когда мы пытаемся назначить значение для типа int, которое больше, чем максимальное значение типа int, оно снова начинается с min value int, например.

2147483648 -will become-> -2147483648
2147483649 -will become-> -2147483647
2147483650 -will become-> -2147483646

После первого значения выражения a есть -2147483648

И когда вы делаете int b = -a; обычно b должен иметь

b = -a --> -(-2147483648) --> 2147483648

Но максимальное положительное значение int равно 2147483647, а 2147483648 больше, чем 2147483647, оно будет возвращаться назад на 1 и станет -2147483648.