在今天刷Java面试题时遇到这样一道题目:
然后提供了四个备选项: [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,没毛病。
我们再来测试一些例子:
分析: 移位32,需要求余,得到求余结果0,所以16 >> 32即是16 >> 0,应该等于16.
移位33,需要求余,得到求余结果1,所以16 >> 33即16 >> 1,结果应该等于8.
移位33,需要求余,得到求余结果1,所以16 << 33即16 << 1,应该等于32.
顺利解决。