Как переполнение работает в java?
Я читал о переполнении, я знаю, что "Overflow - это когда число настолько велико, что оно больше не будет вписываться в тип данных, поэтому система" обертывается "до следующего самого низкого значения и подсчитывает оттуда".
Например:
short s = (short)1921222; // Stored as 20678
В этом примере мы начали отсчет с -32768 (Short.MIN_VALUE)
, но когда я пытаюсь доказать в других целочисленных типах данных, это не похоже на то же самое...
byte b = (byte)400; // Stored as -112
Приведенный выше пример начинался с 0, и это был единственный способ получить -112
Я не знаю, что я делаю что-то неправильно.
Ответы
Ответ 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
, как показано в вашем тесте.