Ответ 1
Изменение знака Integer.MIN_VALUE
вызывает переполнение; вы видите результат этого.
int a = Integer.MIN_VALUE;
int b = -a;
System.out.println("a = "+a + " | b = "+b);
Результат:
a = -2147483648 | b = -2147483648
Я ожидал, что b будет положительным числом.
Изменение знака Integer.MIN_VALUE
вызывает переполнение; вы видите результат этого.
Если вы когда-либо делали что-то вроде этого:
int a = Integer.MAX_VALUE;
a++;
System.out.println(a);
Вы узнаете, что когда что-то превышает максимальное значение типа данных, оно возвращается к своему минимальному значению. И когда значение меньше минимального значения, оно возвращается к максимальному значению.
То же самое происходит и здесь.
Отрицание минимального значения int математически дало бы нам 2147483648, но так как это больше, чем максимальное значение. Он снова возвращается к минимальному значению, которое равно -2147483648.
Забавный факт: отрицание в основном переключает каждый бит от 0 до 1 и от 1 до 0, а затем добавляет один. Попробуйте сделать это до 10000000000000000000000000000000, что и есть значение int min в двоичном формате.
Для базового двоичного объяснения это связано с тем, что подписанные целые числа хранятся с Два дополнения.
Итак, самое отрицательное число в двоичном формате - 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), поскольку он уже побито не добавляет и дополняет дополнение к двум).
Обычно, когда мы пытаемся назначить значение для типа 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
.