一次搞懂:正数 负数 左移<< 右移>> 移位运算规则 移位后的空位添补规则

  • 移运算符 << :把一个数的所有位都向左移动若干位
int i = 1;
i = i << 2; //把i里的值左移2位

为了理解方便,假设 int 占1个字节(8位,实际32位机器占4字节,32位)

i = 0000 0100
i = i << 2 ; 
//结果 i = 0001 0000

此时需要注意的是 int 类型 最左端的符号位
0 表示
1 表示

i = 0100 0000 //十进制为64  111 1111:127   1000 0000:128
i = i << 1 ;  //变为i = 1000 0000 即十进制为-128 变成了最小数
这里是不是一脸问号???接下来解释为什么
计算机中以补码的形式存储数据

/*
正数补码 = 原码
负数补码 = 原码取反+1
*/

-1 原码为1000 0000  0000 0000  0000 0000  0000 0001
-1 反码为1111 1111  1111 1111  1111 1111  1111 1110
-1 补码为1111 1111  1111 1111  1111 1111  1111 1111

所以最小的负数是-2147483647吗?错,不是。

在二进制中,0有两种表方法。
+0 原码为0000 0000  0000 0000  0000 0000  0000 0000
-0 原码为1000 0000  0000 0000  0000 0000  0000 0000
因为0 只需要一个,所以把-0拿来当做一个最小的数-2147483648
这也就是为什么负数比正数多一个的原因(int 范围-2^31 ~ 2^31-1-2147483648 的补码表示为1000 0000  0000 0000  0000 0000  0000 000032位没有原码

注意,这个补码并不是真正的补码,真正的补码是1  1000 0000  0000 0000  0000 0000  0000 0000 溢出

所以在这里只占1个字节带符号的int的最小值为-1280100 0000 << 1 = 1000 0000 (-128

当左移的位数超过该数值类型的最大位数时,编译器会用左移的位数去模类型的最大位数,然后按余数进行移位,如:

int i = 1 //设int占1个字节,即8位 i = 1:0000 0001
i = i << 9;
// 9 % 8 = 1 即此时左移1位 i = 2 :0000 0010
int i = 64 //设int占1个字节,即8位 i = 1:0100 0000
i = i << 9;
// 9 % 8 = 1 即此时左移1位 i = 0 :1000 0000 最高位被丢弃

总结:丢弃高位,0补低位

  • 移运算符 >> :把一个数的所有位都向左移动若干位

符号位向右移动后,正数补0负数补1,也就是汇编语言中的算术右移,同样当移动的位数超过类型的长度时,会取余数,余数是几,移动几位

整型 int 为4个字节32位,那么当我们右移32位会发生什么?35位呢?

原数: 2147483647 (整型最大值)
二进制: 01111111 11111111 11111111 11111111
结果不变

这是因为位移是一个取模的过程
当我们右移4位:4 % 32 = 4
当我们右移32位:32 % 32 = 0 也就是不动
那么当右移33位,那不就是右移1位吗!

  • 无符号右移(没有无符号左移)

无符号右移在右移时,高位补0,也就是不会管你是不是负数
-10 >>> 1
二进制: 01111111 11111111 11111111 11111011 | 0
是这样吗?答案是对的,负数无符号右移,高位同样补0
无符号右移1位后最高位的1变为了0,负数变为了正数

总结
负数右移高位补1
无符号负数高位补0

eg 小测验:

原数: 75
二进制: 00000000 00000000 00000000 01001011
请问 左移25位结果是?
10010110 00000000 00000000 00000000
-1778384896
  • 总结
码制添补代码
正数原码、补码、反码0
负数原码0
补码左移添0
右移添1
反码1
  • 10
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值