文章目录
移位操作符
分为:
左移操作符:<<
右移操作符:>>
其实讲移位操作符之前,先来了解一下计算机中的原码、反码和补码
原码 反码 补码
一个数在计算机内部如果是有符号数,则其最高位作为符号位;
如果符号位为0,表示该数为正数;如果符号位为1,表示该数为负数。(0正1负)
如何求原码、反码和补码呢?
原码:最高位作为符号位,其余各位为数值为(0正1负)
反码:正数的反码和原码相同,负数的反码是在原码的基础上:符号位不变,其余各位按位取反
补码:正数的补码与原码相同,负数的补码是在反码的基础上加1
以下求原反补的过程:
例:求+25
和-25
的原码、反码和补码
①不考虑正负,将25转换成二进制 25D=11001B ② +25 -25 原: 00011001 10011001 反: 00011001 11100110 补: 00011001 11100111
再来看一个
例:求+30
和-30
的原码、反码和补码
①不考虑正负,将30转换成二进制 30D=11110B ② +30 -30 原: 00011110 10011110 反: 00011110 11100001 补: 00011110 11100010
计算机中使用的是补码,什么是补码,怎么去理解补码?
补码可以理解成一个循环;
这里不过多阐述了,如果还有不懂的可以去百度一下!
左移操作符
移位规则:左边抛弃、右边补0
正数左移
代码示例:
int main() { int a = 5; int b = a << 2; printf("%d\n", b); return 0; }
运行结果:
那么这个结果是怎么来的呢?
1、首先把十进制的5转换成二进制
十进制:5
二进制:00000101
写出原码反码补码:
原码:00000101
反码:00000101
补码:00000101
所以5
的补码为:00000101
2、再把补码向左移动2位
为什么向左移动2位?
因为代码是a<<2
!
然后:
于是我们就得到了一个新的补码:00010100
3、转换
再把新的补码转换为十进制的数
也就是把00010100
转换成十进制,得到了20
明白了吗?
负数左移
代码示例:
int main() { int a = -5; int b = a << 2; printf("%d\n", b); return 0; }
运行结果:
那么这个-20
是怎么得来的呢?
1、首先把十进制的-5
转换成二进制
但是我们得先求出5
的原码
十进制:5
二进制:0000101
所以:-5的原码、反码、补码为:
原码:10000101
反码:11111010
补码:11111011
所以-5
的补码为:11111011
2、再把补码向左移动2位
然后:
最后:
于是我们就得到了一个新的补码:11101100
3、回推
这里就不能直接把11101100
转换成二进制了,因为这是-5
所以我们得由:补码 ---> 反码 ---> 原码
,这样逆序的过程,推算出原码
所以我们得到了新的原码:10010111
4、转换
10010100
换算成十进制就是:20
但是因为符号位为:1
,0正1负
所以结果为:-20
这就是左移操作符,懂了吗?
右移操作符
首先右移操作符分为两种:
- 算术右移
- 逻辑右移
移位规则:
- 算术右移:左边用原该值的符号位填充,右边丢弃
- 逻辑右移:左边用0填充,右边丢弃
那么到底是用算术右移还是逻辑右移呢?
主要是取决于编译器的!
我们常见的编译器都是算术右移
算术右移
这里还是拿数字5来举例
正数算术右移
代码示例:
int main() { int a = 5; int b = a >> 1; printf("%d\n", b); return 0; }
运行结果:
1、移动
上面我们已经求出了5
的补码:00000101
看代码给的是向右移动一位
然后:
所以得到新的补码:00000010
2、转换
因为是正数,所以我们直接把00000010
转换成十进制:2
负数算术右移
代码示例:
int main() { int a = -5; int b = a >> 1; printf("%d\n", b); return 0; }
运行结果:
1、移动
上面我们已经求出了-5
的补码:11111011
看代码给的是向右移动一位
然后:
所以得到新的补码:11111101
2、回推
我们得以:补码 ---> 反码 ---> 原码
,这样逆序的过程,推算出原码
所以我们得到了新的原码:10000011
3、转换
10000011
换算成十进制就是:3
但是因为符号位为:1
,0正1负
所以结果为:-3、
这就是算术右移的方法,学废了吗?
逻辑右移
逻辑右移的方法和左移操作符有点类似
就是:右边丢弃,左边空的补0
这里就不演示啦!