Переполнение Короче в java

У меня есть один вопрос о short типе данных в Java. Я знаю, что диапазон для коротких составляет от -32768 до 32767.

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

 short a = 30000; a = (short) (a+a); 

результат -5536 .

Так математика 32768 + 32768 = 65536 , 6000 – 65536 = -5536 .

Я знаю, что он делает, но я не знаю, почему это так.

Может ли кто-нибудь объяснить логику или почему Java делает это так?

Что происходит, так это то, что ваш номер обертывается. Более конкретно, у вас есть номер 30 000, который в двоичном формате:

 0111 0101 0011 0000 

Когда вы добавите его себе и несете 1, вы получите:

 1110 1010 0110 0000 

(Примечание: очень просто умножить число на 2 в двоичном формате – просто сдвиньте все биты один влево.)

Короткий – это подписанное число с использованием двух дополнений , что означает, что самый левый 1 действительно является знаком минус; это число составляет -5536.

Если вы снова умножите это число на 2, вам понадобится более 2 байтов для его представления. Так как у вас не более 2 байтов в short , дополнительные биты просто будут отброшены, когда результат int выражения будет сужен до short . Сделайте это достаточно, и у вас будет 0 как самая левая цифра; число положительное снова. И тогда в конце концов у вас будет 1 снова как самый левый; число отрицательно снова. В конце концов вы переместили бы все 0s в число; умножая любое целое на 2 достаточно раза, всегда будет 0 (в частности, если это N-разрядное число, умножая его на 2 N раз, всегда будет 0).

Если вы не сузились до short , вы все равно в конце концов закончите цифры в int (когда вам нужно 33 или более бит) – это приведет к отбрасыванию лишних цифр, которые являются целыми переполнениями . То же самое произойдет, если любой из аргументов будет long , хотя это займет 65 + бит.

Во-первых, ваше дополнение преобразует шорты в int, потому что аддитивный оператор выполняет двоичную числовую рекламу на операндах.

Поэтому результатом является int tmp = 60000;

Затем этот результат преобразуется обратно в короткий через сужение примитивного преобразования :

Сужение преобразования знакового целого числа в интегральный тип T просто отбрасывает все, кроме n бит младшего разряда, где n – количество бит, используемых для представления типа T.

Другими словами, 60000 = 1110 1010 0110 0000b но короткий подписан так, что начальный 1 является знаком и использует 2 дополнения, вы получаете эквивалентное короткое значение, которое составляет -5536: 1110 1010 0110 0000 => 0001 0101 1010 0000 (вы отрицать все биты, добавить один и поставить знак минус)

  0111 0101 0011 0000 + 0111 0101 0011 0000 ______________________ 1110 1010 0110 0000 

short Java кодируется в двух дополнениях. В двух дополнениях наиболее значимый бит рассматривается как знаковый бит, 0 положителен и 1 и отрицателен.

 1110 1010 0110 0000 = -5536 in two's complement 

Это связано с двоичным представлением данных. В большинстве систем используется нечто, называемое дополнением 2. Положительные числа ведут себя нормально, если у них есть 0.

 0010 = 2 

Чтобы перевернуть знак, замените все 0 на 1 и добавьте 1:

 -2 = 1110 

Итак, что произойдет, если мы возьмем наибольшее положительное число, скажем, 01111 (в двоичном формате) и добавим 1? Мы получаем 10000, что является отрицательным числом (Int.min_val, в частности). Это то, что происходит, когда целое число переполняется.

http://en.wikipedia.org/wiki/Two%27s_complement

Давайте будем гением компьютера.