负数的左右位移运算和无符号位移,>>,>>>

上一篇讲了关于java基本数据怎么进行加减运算,勾起了好奇心,又去看了一下二进制的位移运算.以前我一直以为位移运算就是乘以或除以2的次方的一种快速运算方式,今天一看还真不是那么回事.
首先如果是一个正数进行位移运算,因为正数的补数是它自己,所以符合我之前的理解,就是乘以或除以2的次方,而且因为多出的位数都是用0填充,所以>>和>>>运算出来的结果是一样的.但是负数进行运算就不一样了.

先出几个题:
1.-1>>2

2.-1<<2
3.-1<<32
4.(byte)-1<<8

5.-1>>>2
6.-1>>>32
7.-1>>>33

各位有兴趣也可以算算结果是多少?

第一题-1>>2
补数公式:X=~x+1(符号位不变)
首先算出-1的补码为:
1111 1111 1111 1111 1111 1111 1111 1111 
向右移动两位,首位用符号位补充,还是:
1111 1111 1111 1111 1111 1111 1111 1111
也就是a=-1.

第二题-1<<2
所以-1补数为:
1111 1111 1111 1111 1111 1111  1111 1111
向左移动两位得,空位用0补充,就是
1111 1111 1111 1111 1111 1111  1111 1100
因为这是补数,而且是负数,所以按上面公式可以推导出x=~(X-1)
1111 1111 1111 1111 1111 1111  1111 1111+
1111 1111 1111 1111 1111 1111  1111 1100=
1111 1111 1111 1111 1111 1111  1111 1011
舍掉最高位,符号位不变,取反得到1000 0100,所以c=-1<<2=-4

第三题,-1<<32,按照第二题推导,结果应该为:
0000 0000 0000 0000 0000 0000 0000 0000
也就是0,可是这是错的,为什么?

因为java底层是C语言写的,而C语言规定位移运算,就是规定如果超出数字的界限,它会从头开始.所以转了一圈,它又回来了
int a=a>>>32

第四题,(byte)-1<<8,按照第三题的结果,它的结果也应该是-1,可是实际上,结果为-128.
因为在进行<<运算时,会把数字先转为32位,在进行运算,当然如果它本来是long类型,那么就是64位.
所以左移8位并并没有超出它的界限,所以结果是负2的负8次方即-128

第五题-1>>>2
-1补数:
11111111 11111111 11111111 11111111
,>>>和>>不同的是,不管正负,首位以0填充,所以结果是:
00111111 11111111 11111111 11111111
因为这是正数,所以这就是最后的结果就是1073741823

第六题-1>>>32,有了第三题的经验,这题结果不用算也知道了就是-1.

第七题-1>>>33
其实-1>>>33=-1>>>1=
01111111 11111111 11111111 11111111=2的32次方-1.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值