Подтвердить что ты не робот

Как переполнение работает в java?

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

Например:

short s = (short)1921222; // Stored as 20678

В этом примере мы начали отсчет с -32768 (Short.MIN_VALUE), но когда я пытаюсь доказать в других целочисленных типах данных, это не похоже на то же самое...

byte b = (byte)400; // Stored as -112

Приведенный выше пример начинался с 0, и это был единственный способ получить -112

Я не знаю, что я делаю что-то неправильно.

4b9b3361

Ответ 1

Спецификация Java Language говорит:

Интегральные типы - это байты, короткие, int и long, значениями которых являются 8-битные, 16-разрядные, 32-разрядные и 64-разрядные подписанные два символа-дополнения, соответственно, и char, значения которых 16-разрядные целые без знака, представляющие кодовые единицы UTF-16.

Итак, short и byte являются целыми двумя целыми числами.

short - 16 бит, то есть он может содержать 2 ^ 16 = 65536 разных значений. После 65536-го значения оно переполняется.
1921222 по модулю 65536 - 20678. Это меньше 32768 (2 ^ 15, точка поворота для двух дополнений), поэтому мы сохраняем положительное число.

byte - 8 бит, то есть он может содержать 2 ^ 8 = 256 разных значений. Этот поток переполняется после 256-го значения. 400 по модулю 256 составляет 144. Это значение выше 128, точка поворота для двух дополнений - следовательно, это будет интерпретироваться как отрицательное два дополнительных номера.

Ответ 2

Листинг усекает число. (JLS)

0000 0001 1001 0000

проигрывает старший байт, чтобы стать

1001 0000

который равен -112.

Ответ 3

В java, byte примитивный тип - это 8 bit подписанное целое число, поэтому вы получили -112 от вызова:

byte b = (byte) 400;

Вы можете избежать этого и получить свое недописанное значение, добавив двоичный код с помощью 0xFF следующим образом:

int b = (byte) 400 & 0xFF;

Для получения дополнительной информации вы можете проверить:

Ответ 4

В дополнение к другим ответам вы также можете получить этот ответ вручную.

В Java тип данных byte представляет собой 8-разрядное целое число со знаком. Значения находятся в интервале [-128, 127]. Если у вас есть значение 400, и вы хотите увидеть фактическое значение для этого типа, вы можете вычесть размер интервала с этого номера, пока не достигнете значения, которое находится внутри интервала.

Как я уже сказал, byte - 8 бит, поэтому размер интервала 256. Вычтите это из вашего начального значения: 400 - 256 = 144. Это значение все еще находится за пределами интервала, поэтому вам нужно снова вычесть: 144 - 256 = -112. Это значение теперь находится внутри интервала и действительно является значением, которое вы видели в своем тесте.

То же самое верно для вашего первого примера: short - 16 бит и подписан, поэтому интервал [-32768, 32767] с размером 65536. Выполнение повторного вычитания из значения 1921222 в конечном итоге даст вам значение 20678, как показано в вашем тесте.