二进制位移的略解带符号右移>>和不带符号右移>>>,左移<<

移位操作:

关于数的移位,特别需要注意:
1、正数,三码(源码、反码、补码)相同,所以无论左移还是右移都是补0.(左移则表示放大2的N次方,右移表示缩小2的N次方)

2、负数的补码就需要注意,左移在右边补0,右移需要在左边补1

 有一个很有趣的误区是,认为符号位保持不变,仅仅移动数据位,这是不对的,因为无论数据位还是符号位,都是二进制,在整体大迁移的过程中,符号位也是要跟随潮流的。只不过,为了保证右移后,和原来的符号数一样,因此,负数在右移时左边补

计算机表示数字正负不是用+ -加减号来表示,而是用最高位数字来表示,0表示正,1表示负

左移<<:向左移位,符号后面的数字是移了多少位,移的位用0补齐,例如2进制数01111111左移一位后变为11111110,移位是字节操作。

右移>>:向右移位,符号后面的数字是移了多少位,移的位用符号位补齐,例如01111111右移一位后变为00111111,而10000000右移一位后变成11000000,因为符号位是1。

右移

demo1

>>> --- 右移运算符,它表示是将运算符左边的对象向右移动运算符右边指定的数,
并且在高位补0.

int a = 16;int b = 2;
System.out.print(a>>>b); 结果是:4

>> --- 带符号右移运算符,它表示将运算符左边的运算对象,
向右移动运算符右边指定的位数。如果是正数,在高位补零,如果是负数,则在高位补1int a = 16,c = -16;int b = 2,d = 2;
System.out.print(a>>b); 结果是:4 
System.out.print(c>>d);-4



综上所述,其实右移n位,就相当于除于2的n此方,这里的右移是>>带符号右移;

如果是正数的话,其实带符号右移>>和无符号右移>>>是一样的,都可以认为是除以2^n次方

demo2

demo2-带符号

负数:例如-4>>2(高位补1)
首先写出-4的二进制数源码,因为是负数所以最高位为1   (负数的源码是负数的绝对值)

1000 0100

然后写出-4反码:保证符号位不变,其余位置取反

1111 1011(反码)

最后写出-4的补码:在反码的基础上加1

1111 1100(补码)

右移2位: 在高位补1

1111 1111

根据补码写出原码才是我们所求的结果, 保留符号位,然后减1取反       (或按位取反再加上11111 1110(减1的结果)

1000 0001(取反的结果)

结果为:-1

demo2-无符号


无符号右移>>>(不论正负,高位均补0)  注意:无符号,所以都是当正数操作的
正数:例如4>>>2

与4>>2的运算相同,结果也为1

负数:例如-4>>>2

首先写出-4的二进制数,因为是负数所以最高位为1

1000 0100

然后写出-4补码:保证符号位不变,其余位置取反加1(从右往左遇到第一个1,然后剩下的全部取反就是了)

1111 1100(补码)

右移2位: 在高位补0

0011 1111

结果为:63

没有无符号左移,因为:位运算中左移跟符号没有关系的, 因为最高位就是符号位 例如8位的byte中最高位如果是 1那就表示负数
如果是左移一位, 那么最高位就会丢掉, 最低位补0 1111 1111 << 1 就会变成 1111 1110

左移<<

<<表示左移,不分正负数,低位补0,将一个数左移n位,就相当于乘以了2的n次方

规则是带符号位移,高位移出,低位补0,移动位数超过该类型的最大位数,则进行取模,如对Integer型左移34位,实际上只移动了两位。左移一位相当于乘以2的一次方,左移n位相当于乘以2的n次方。

这里有个巧妙的见解
2进制的基数为2
所以
类似十进制扩大10倍,相当于×2
类似十进制缩小10倍,相当于÷2
即左移或右移N位等于扩大或缩小2的N次方倍

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值