今天有同学提问一个问题:
int i = 1;//32bit
i=i<<32;
之后i=?;
按照之前的理解:32位的整型数据1的二进制为:0000 0000 0000 0000 0000 0000 0000 0001,
往左移一位将变成:0000 0000 0000 0000 0000 0000 0000 0010;
往左移两位将变成:0000 0000 0000 0000 0000 0000 0000 0100;
........
那么向左移31位会变成: 1000 0000 0000 0000 0000 0000 0000 0000;
以上结果都在VS2005的环境下验证是正确的。那么按照以上规律,向左移32位应该会是这样:
0000 0000 0000 0000 0000 0000 0000 0000
我猜想得到的结果是0,但是实际结果是1。这一点让我很不解,于是在网上提问,有人帮我解决了疑问:
左移运算时,当要移的位数n大于或者等于被移数据类型位数m的时候,将n对m求余再移位,即向左移n%m位。
也就是说i<<32,其实就是i<<(32%32),也就是i<<0,那么i还是1咯~
好的,那么接下来还有一个问题:i<<-1呢?应该是多少?纳尼?还有移负数位的啊???
是的,还有移负数位的,那么结果是多少呢?猜都不知道怎么猜的答案,实验结果是:0x8000 0000;
那么为什么会是这样呢?
于是我这样想:(以下全代表个人观点,不知道对不对)
负数在内存中是以补码的形式存储的,-1的补码就是:0xffffffff,
于是我将代码中的i<<-1改为i<0xffffffff,得到的结果仍然是0x8000 0000,
于是我猜想左移的时候,将移的位数m是当做无符号数来处理的。那么当i<<0xffff ffff是时候其实就是,i<<(0xffff ffff%32)即i<<31,那么结果刚好就是
0x8000 0000。
不知道我这样理解对不对。还请各位指教。