参考两篇博客(浅谈操作符(1)-CSDN博客 浅谈操作符(2)-CSDN博客)
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int a = 5;//定义a=5
a = a << 1;//a左移一位
printf("%d\n", a);//输出a
return 0;
}
显然,左移操作符就是这样,而且左移的位数(右移也可以)可以由自己来确定,可以移动多位,让我们再来一次:
00000000000000000000000000000101 (还是5,还没有移动)
00000000000000000000000000000101 (我们给它左移五位)
00000000000000000000000010100000 (给它移动后补0),现在的值就已经变成了160了(32+128),用代码来实验一下:
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int a = 5;
a = a << 5;//左移5位
printf("%d\n", a);
return 0;
}
这就是正数的左移操作符的使用方法了,看似还是十分简单的——因为正数的原码、反码、补码都相等,相当于只需要知道其原码,就可以知道反码和补码了,十分的方便。但我们生活中大抵是少不了负数(非正数)的存在,负数的移动相对正数而言更加的麻烦,让我娓娓道来。
我们还是先举个例子,我们来个-5,我们将-5用二进制表示出来:
10000000000000000000000000000101 (最前面的1是符号,二进制首位1为负数,0为正数),这是它的原码,让我们求一下它的反码——首位(符号位不变),其它位按位取反:
11111111111111111111111111111010(这就是-5的反码表示),补码就是反码+1,那就是:
11111111111111111111111111111011,这便是-5的补码了,我们还是给它左移一位,来浅看一下:
11111111111111111111111111111011 (左移前)
11111111111111111111111111111011 (左移一位)
11111111111111111111111111110110 (完成了左移并补0)
看到这里,你也许会很惊讶——难道-5只是移动了一位,就变得这么大了吗?我要输出它,一个整型还不够?其实不是这样的,虽然在内存中存储的是数的补码,但是输出的却是数的原码,所以说我们先求出了补码并移动了还不够,我们还需要将移动后的数字来再求它的原码之后得到的数字才是真正的负数左移的值,让我们来求其原码:(补码先-1,再按位取反就是其原码了。)
11111111111111111111111111110101(-1)
10000000000000000000000000001010(按位取反)这便是-5左移1位后的原码了,它的值是-10,让我们验证一下:
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int a = -5;
a = a << 1;
printf("%d\n", a);
return 0;
}
总结
左移操作符相当于将数的二进制的补码向左移动一位,然后在末尾补0;正数的原码、反码、补码都是一样的,所以说相对简单;但值得一提的是:负数的原码、补码不同,需要注意这一点;并且更重要的一点是——移动的是数的补码,但是真正输出的却是数的原码,所以说在移位负数时,是先算出其补码,再移动,再根据补码算出其移动后的原码,再进行输出的。
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int a = 5;
a=a >> 1;
printf("%d\n", a);
return 0;
}