移位运算符的效果
Posted fy_闷油瓶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了移位运算符的效果相关的知识,希望对你有一定的参考价值。
目录
移位运算符介绍
以C语言为例,在C语言中移位运算符是指将二进制位向左或者向右移动n位,其操作数必须为整型。左移运算符:<< ;右移运算符:>>
一、左移运算符
1.1左移运算规则
左移运算符将运算对象每一位二进制的值向左移动指定的位数,左末端的值丢失,右侧补0。
例如:-5用二进制表示为
10000000 00000000 00000000 00000101(原码)
11111111 11111111 11111111 11111011 (补码)
左移1位后等于-10:
11111111 11111111 11111111 11110110(补码)
10000000 00000000 00000000 00001010(原码)
1.2左移的运算效果
首先我们看一段代码:
#include<stdio.h>
int main()
int a = 2, b = -2;
a = a << 1;
b = b << 1;
printf("a=%d,b=%d", a, b);
return 0;
程序最后运行的结果为:
我们可以看到,左移移位后,相当于在原来的基础上乘2,这是巧合么还是必然呢?
对于正数而言,转换成二进制后,第n位的权重为 2^ (n-1), 当左移一位后,原本的第n位到了n+1位,权重变成了 2^n,所以左移一位相当于乘2。对于负数,同样的道理,左移一位也相当于乘2。哪怕是超过了整型范围,其结果也相当于乘2。
例如:
#include<stdio.h>
int main()
int a = 1073741825;
int c = 2 * a;
int b = a << 1;
printf("%d\\n", b);
printf("%d\\n", c);
return 0;
#include<stdio.h>
int main()
int a = -1073741825;
int c = 2 * a;
int b = a << 1;
printf("%d\\n", b);
printf("%d\\n", c);
return 0;
二、右移运算符
2.1右移运算规则
右移1位,将当前操作数的所有二进制位向右移动一位。对于无符号类型,左侧补0;对于有符号类型,其结果取决于机器。左侧可以补0,也可以补1。(算数右移左侧补符号位,逻辑右移左侧补0)VS2019中遵循算数右移规则,因此我们对算数右移进行分析。
例如:5用二进制表示为
00000000 00000000 00000000 00000101
左移1位后等于2:
00000000 00000000 00000000 00000010
-5用二进制表示为
10000000 00000000 00000000 00000101(原码)
11111111 11111111 11111111 11111011 (补码)
左移1位后等于-3:
11111111 11111111 11111111 11111101(补码)
10000000 00000000 00000000 00000011(原码)
2.2 右移的运算效果
正数
右移1位原本第n位将被移到第n-1位,权重将会由2^(n-1)变为 2^(n-2),因此相当于除以2
负数
当N为奇数时:
符号位为1,最低为也为1
1××××××× ×××××××× ×××××××× ×××××××1(原码)
1******* ******** ******** *******1(补码)
其中 * 表示×取反后的结果
右移1位后变成
11 ****** ******** ******** ********(补码)
10×××××× ×××××××× ×××××××× ×××××××(×+1)(原码)
将原码换种方式表示
10×××××× ×××××××× ×××××××× ×××××××× +1
由于符号位是负,因此在最后一位上加上1,相当于加上
10000000 00000000 00000000 00000001(即-1)因此相当于将原来的数减去1,可以看见,在减1之前,相当于原来的原码,每一位的权重变为了原来的1/2,因此当N为基数时,右移1位相当于除以2再减1,即N=N/2-1。
因为N为基数,所以 N/2 - 1 =(N-1) /2。
当N为偶数时,符号位为1,最低为为0
1××××××× ×××××××× ×××××××× ×××××××0(原码)
1******* ******** ******** ******* 1(反码)
1******* ******** ******** ******( *+1)0(补码) 最后1位1加上1会向高位进1,我们表示为 *+1
当N向右移动1位后变成
11****** ******** ******** ******( *+1) (补码)
10×××××× ×××××××× ×××××××× ××××××××(原码)
这里由补码求原码的时候,我们用原码=(补码-1)取反,就可以把( *+1)的1处理掉,从而得到
10×××××× ×××××××× ×××××××× ××××××××,和移位前相比,每位的权重变为了原来的1/2,因此N为偶数时,右移1位,相当于除以2,即N=N/2。
因为N为偶数,所以N/2 = (N-1)/2。
当操作数为负时,左移一位相当于(N-1)/2。
以上是关于移位运算符的效果的主要内容,如果未能解决你的问题,请参考以下文章