Операция сдвига бит не возвращает ожидаемый результат

Почему Java возвращает -2147483648, когда я смещаю бит 1 < < 63?

Ожидаемый результат: 9 223 372 036 854 775 808, проверенный с Wolfram Alpha и моим калькулятором.

Я тестировал:

System.out.print((long) (1 < (63)));

2 ответа

Здесь важно отметить строку

System.out.print((long)(1 << (63)));

Сначала вы берете (1 << 63), а затем вы бросаете до конца. В результате вы фактически сдвигаетесь влево в целых числах, поэтому длинный бросок не имеет никакого эффекта. Поэтому, если сдвинуть 63 бита влево, значение min будет минимальным, а не длинным.

Но есть еще один, более важный момент. Java longs всегда подписаны, поэтому даже строка

System.out.print(1L << 63);

даст отрицательное число. Под двумя дополнениями, когда самый левый бит равен 1, число отрицательно.

Фактически вы не можете представить число 2 63= 9223372036854775808 в примитивном типе Java, потому что это число больше максимального, а long является самым большим примитивным типом. Вы можете представить это число как BigInteger. Вы даже можете сгенерировать его с помощью сдвига влево на 63 с кодом

BigInteger.ONE.shiftLeft(63)


У вас есть целочисленное переполнение [дважды].

1 << 32 == 1
1 << 31 == -2147483648 [ becuase this is the binary representation in 2 complement for -2147483648]
1 << 63 == 1 << (32 + 31) == (1 << 32) << 31 == 1 << 31 == -2147483648

Когда вы выполняете (long)(1 << (63)), вы делаете результат 1 << (63) [который равен -2147483648] на long - и он не меняет его значения.

licensed under cc by-sa 3.0 with attribution.