All shifts are done mod 32 for ints and mod 64 for longs.
From section 15.19 of the spec:
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 & (§15.22.1) with
the mask value 0x1f. The shift
distance actually used is therefore
always in the range 0 to 31,
inclusive.
If the promoted type of the left-hand
operand is long
, then only the six
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 & (§15.22.1) with
the mask value 0x3f. The shift
distance actually used is therefore
always in the range 0 to 63,
inclusive.
As for why the language was designed that way - I don't know, but C# has the same design decision. Here's what the annotated ECMA C# spec says:
C# deliberately keeps
implementation-defined behaviors to a
miinimum. They are accepted only when
the performance impact of forcing
uniform behavior would be excessive
(such as for some floating-point
precision issues). Hence, the size of
each integral type is precisely
specified, and the character set is
fixed to Unicode.
For shift operations, too, uniform
behavior is specified. It can be
achieved using a single extra
instruction (& 0x1F or & 0x3F) that
incurs only a tiny cost on modern
processors, especially since it does
not reference memory. Unlike for
floating-point operations, the
difference in shift behavior would be
dramatic if left to the whim of the
processors; rather than a small
difference in precision, completely
different integral results would be
produced.
In making this decision the committe
studied reference materials for a
number of different processor
architectures. There is little
consistency in the behavior for shift
counts outside the range -32..+32 for
32-bit operands, and respectively
-64..+64 for 64-bit operands.
(There's then a list of some examples.)
This seems an entirely reasonable explanation to me. Consistency is definitely important, and if it would be impossible to implement different consistent behaviour in a performant way on some systems, I think this is a reasonable solution.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…