Java整数左移的奇怪结果
Weird result of Java Integer left shift
我现在对java左移操作有点困惑,
1<<31 = 0x80000000 --> this I can understand
但是
1<<32 = 1 Why is this?
1<<33 = 2
看起来像更多的移位值,取值的模数 32。
感谢大家的回复和JLS的引用
我只是想知道更多。知道以这种方式设计的原因吗?还是只是一些惯例?显然 C 没有这个怪癖?
Thanks to @paxdiablo. Looks like C declares this behaviour undefined.
这里有一些个人的假设:
ARM architecture Reference Manual A7.1.38
Syntax
LSL Rd, Rm, #immed_5
where:
Rd Is the register that stores the result of the operation.
Rm Is the register containing the value to be shifted.
immed_5 Specifies the shift amount, in the range 0 to 31.
在指令层面,立即数immed_5只占用5位,避免无意义的操作,从而节省一些指令space。我想高级语言只是统一了这个约定,以避免在编译为指令时进行无意义的工作。
根据 Java 语言规范 15.19. Shift Operators
(略有释义):
If the promoted type of the left-hand operand is int
, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator &
with the mask value 0x1f
,or 0b11111
. The shift distance actually used is therefore always in the range 0
to 31
, inclusive.
这意味着(例如)33
,作为 6 位二进制 100001
,在使用之前被缩减为 5 位 00001
。所以 x << 33
等同于 x << 1
.
System.out.println(Integer.toBinaryString(1 << 32));
将二进制 1(10) 向左移动 32 次。因此:十进制为 1
System.out.println(Integer.toBinaryString(1 << 33));
现在,int 是 4 个字节,因此是 32 位。所以当你移动 33 时,它相当于移动 1。因此: 2 in decimal
我现在对java左移操作有点困惑,
1<<31 = 0x80000000 --> this I can understand
但是
1<<32 = 1 Why is this?
1<<33 = 2
看起来像更多的移位值,取值的模数 32。
感谢大家的回复和JLS的引用
我只是想知道更多。知道以这种方式设计的原因吗?还是只是一些惯例?显然 C 没有这个怪癖?
Thanks to @paxdiablo. Looks like C declares this behaviour undefined.
这里有一些个人的假设:
ARM architecture Reference Manual A7.1.38
Syntax LSL Rd, Rm, #immed_5
where:
Rd Is the register that stores the result of the operation.
Rm Is the register containing the value to be shifted.
immed_5 Specifies the shift amount, in the range 0 to 31.
在指令层面,立即数immed_5只占用5位,避免无意义的操作,从而节省一些指令space。我想高级语言只是统一了这个约定,以避免在编译为指令时进行无意义的工作。
根据 Java 语言规范 15.19. Shift Operators
(略有释义):
If the promoted type of the left-hand operand is
int
, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator&
with the mask value0x1f
,or0b11111
. The shift distance actually used is therefore always in the range0
to31
, inclusive.
这意味着(例如)33
,作为 6 位二进制 100001
,在使用之前被缩减为 5 位 00001
。所以 x << 33
等同于 x << 1
.
System.out.println(Integer.toBinaryString(1 << 32));
将二进制 1(10) 向左移动 32 次。因此:十进制为 1
System.out.println(Integer.toBinaryString(1 << 33));
现在,int 是 4 个字节,因此是 32 位。所以当你移动 33 时,它相当于移动 1。因此: 2 in decimal