位移运算符。有符号和无符号。

23

我正在使用网络上的临时笔记来准备SCJP考试。

根据我的笔记,>>运算符应该是有符号右移,符号位从左侧带入。而左移运算符<<应该保留符号位。

然而,在尝试中,我能够使用<<运算符改变符号(例如,Integer.MAX_VALUE << 1计算结果为-2),但是我从未能够使用>>运算符改变符号。

我一定是在哪里误解了,但是在哪里呢?


看看 -2 << 31 给你什么结果。 - Stephen C
2个回答

54

">>" 是带符号的,因为它保留了符号。它使用一个数字的二进制表示中最左侧的位作为填充位。例如:

    | this value is used as a filler 
    11011011 
 >> 11101101  

    01010010
 >> 00101001 

">>>"是此运算符的无符号版本。它总是使用零作为填充物:

    11011011 
>>> 01101101  

    01010010
>>> 00101001
在二进制表示中,最左边的数字决定了数值的符号。如果是'1'则代表负数,如果是'0'则代表正数。因此,使用最左边的数字作为填充位可以保持数值的符号不变。

啊,好的,我明白了右移运算符应该如何工作。谢谢!但是为什么我能用“<<”改变符号? - user271052
因为它向另一个方向移位,而最左边的数字取决于原始数字。它使用0作为填充符,但将其附加到数字的右侧。 - Roman
整数的符号由其最左边位的值确定。如果在它是 1 或者 0 的时候移入了相反的值,结果的符号会改变。 - Stephen C
好的,那么基本上我的笔记中关于左移运算符(<<)的信息是不正确的。如果我理解正确的话:1)从右侧填充0。 2)将移位(最左边)符号位并用右侧的位替换它。 - user271052

3
移位的概念是可以通过乘以或除以2的幂来实现(<< 1 相当于 *= 2,>> 2 相当于 /= 4),这就是为什么存在有符号移位的原因。然而,无符号移位并不一定保留符号。正如你所提到的,<< 运算符并没有实际上保留符号;它只是在你的例子中碰巧保留了符号。尝试对 2,147,483,647 进行左移操作,它不会保持为正数。他们不费力地尝试制作“有符号”的左移,是因为如果数字从正变为负(或反之亦然),那么你已经超出了变量类型的范围。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接