左移操作符(<<)和右移操作符(>>)

以前在学C语言的时候遇到了左移(右移)操作符。在知道这两种操作符是将一个十进制数的二进制形式按位左移(右移)时,便产生了一个疑问,就是移动时产生的多余的位是用1补还是用0补,于是就写了一个程序验证一下。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     int i = 3;
 8     i = i << 2;
 9     cout << i << endl;
10     return 0;
11 }

程序结果如下:

12

3的二进制数表示是11,移过两位后显示的数字是12,12的二进制表达是1100,可以得知位移过后产生的空缺是由0填补的。

一个整数x被左移n位时产生的数是x*2n

一个整数x被右移n位时产生的数是x/2n

后来在学习的过程中就有了一个想法,那就是如果使用位移运算符使数字强行越界,那么会产生什么结果呢?

先来看右移:

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     int i = 3;
 8     i = i >> 1;
 9     cout << i << endl;
10     i = 1;
11     i = i >> 2;
12     cout << i << endl;
13     i = 1;
14     i = i >> 3;
15     cout << i << endl;
16 
17     return 0;
18 }

 

运行结果是:

1
0
0

3的二进制数是11,右移一位是01,于是第一个结果是1,而右移两位是00,所以第二个结果是0,右移三位以后还是0。由此可以看出因为右移而出界的数字将会被丢失,所以对数字进行右移操作时需要非常谨慎,数字被右移以后的结果可能会失去精度。

如果整数x可以被2^n整除的话,右移n位将会得到正确地结果;反之,如果不能被整除,结果将会是两数相除的商,而余数将会被舍弃。

接下来是左移:

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     int i = 1;
 8     i = i << 64;
 9     cout << i << endl;
10     i = 1;
11     i = i << 65;
12     cout << i << endl;
13 
14     return 0;
15 }

 

运行结果为:

1
2

首先需要说明的是运行程序的机器是64位机。

发现如果左移超过了存储单元长度,那么这次位移的结果就是位移位数减去存储单元长度后再进行位移的结果。

posted @ 2020-08-13 22:40  江南湖西北  阅读(1421)  评论(0编辑  收藏  举报