下面是我在刷题过程遇到的问题,并给出了自己的解决方案,如果其中存在错误,还行各位看官不吝赐教,及时指出。
在今天刷Java面试题时遇到这样一道题目:
问题
public class Test{
public static void main(String[] args){
int num = 32;
System.out.println(num >> 32);
}
}
然后提供了四个备选项:
[A].32 [B].16
[C].1 [D].0
我:选D,这还用看?老师上课讲的清清楚楚明明白白,num >> 1就是将num缩小1/2,num >> 2就是将num缩小1/2的1/2。我用脚指头都能想到 num >> 32不就是一直减少一半?那就等于0选D呗,
兴高采烈翻开答案册子。
正确答案:A。没错,就是32.
。。。
凭实力打脸,脚指头他再也不香了.
我左思右想,几乎这样一道题抓破了脑袋。擦,没毛病啊,但是实在不清楚他为毛等于32啊。
========= 分割线 ========
分析
一阵抓耳挠腮的挣扎之后,终于有了结果:
背景知识:Java中一个int型数值整4个字节,即32位。
我们再来看看文章开头的32 >> 1这种情况:
毋庸置疑,结果等于16.
如果向右移动5位呢?将会得到32个0,结果为0,继续后移,仍然为0(我这不是废话嘛),这样看来文章开头选D合情合理。
可是如果我们再来考虑左移位呢?将1 << 1,得到2,如果左移31位呢?是不是得到下面的这种情况?
考虑符号位的情况下,得到了-0,你没看错,无限制的扩大2倍,最终得到的数为0。
结论
现实中肯定不会允许这样的事情存在,为了解决这个问题,对此有一个规定:当int型数据进行左移位时,如果左移的位数大于等于32时,会首先对位数求余,然后再将得到的结果进行左移位。右移位时也有相同的处理方法
带着这个结论,就能完美的解释为什么32 >> 32 = 32了。左移位数等于32,所以应该对32取余,得到0,最终的式子转化为32 >> 0 = 32,没毛病。
我们再来测试一些例子:
测试1
public class Test {
public static void main(String []args) {
System.out.println(16 >> 32);
}
}
分析:
移位32,需要求余,得到求余结果0,所以16 >> 32即是16 >> 0,应该等于16.
测试2
public class Test {
public static void main(String []args) {
System.out.println(16 >> 33);
}
}
移位33,需要求余,得到求余结果1,所以16 >> 33即16 >> 1,结果应该等于8.
测试3
public class Test {
public static void main(String []args) {
System.out.println(16 << 33);
}
}
移位33,需要求余,得到求余结果1,所以16 << 33即16 << 1,应该等于32.
顺利解决。