问题
I'm a little confused now by java left shift operation,
1<<31 = 0x80000000 --> this I can understand
But
1<<32 = 1 Why is this?
1<<33 = 2
Looks like more shifting values, modulus 32 of the value is taken.
Thanks everybody for the replying and giving the quote from JLS.
I just want to know more. Any idea of the reason why it's designed in this way? Or is it just some convention? Apparently C doesn't have this quirk?
Thanks to @paxdiablo. Looks like C declares this behaviour undefined.
I have some personal assumption here:
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.
On instruction level, the immeidate immed_5 takes only 5 bits to avoid meaningless operations so as to save some instruction space. I guess high level languages just unitize this convention to avoid meaningless effort when compile to instructions.
回答1:
As per the Java Language Specification 15.19. Shift Operators
(slightly paraphrased):
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.
That means that (for example) 33
, being the 6-bit binary 100001
, is reduced to the 5-bit 00001
before being used. So x << 33
is identical to x << 1
.
回答2:
System.out.println(Integer.toBinaryString(1 << 32));
Shifts binary 1(10) by 32 times to the left. Hence: 1 in decimal
System.out.println(Integer.toBinaryString(1 << 33));
Now, int is of 4 bytes,hence 32 bits. So when you do shift by 33, it's equivalent to shift by 1. Hence : 2 in decimal
来源:https://stackoverflow.com/questions/34193787/weird-result-of-java-integer-left-shift