C语言中左移右移运算规则

https://blog.csdn.net/u012745229/article/details/51405332

左移

    int i=1;
    i=i<<2;//把i里面的值左移2位
  • 1
  • 2

1的2进制是 
000…0001 
(这里前面0的个数和int的位数有关,32位机器,gcc里有31个0),左移2位之后变成: 
000…0100, 
也就是10进制的4,所以说左移1位相对于乘以2的n次方(有符号数不完成适用,因为左移有可能导致变化,下面解析原因)

//需要注意的一个问题是int类型最左端的符号位和移动出去的情况,我们知道,int是有符号的整形数,左端的1位是符号为,即0为正1为负,那么用移位的时候就会出现溢出,如:
int i=0x40000000;//16进制的40000000,为2进制的01000000...0000
i=i<<1;
//那么,i在移动1位之后就会变成0x80000000,也就是2进制的100000...0000,符号位被置1,起位全是0,变成了int类型所能表达的最小值,32为的int这个值是-2147483648,溢出,如果在接着把i左移1位会出现什么情况呢?在c语言都采用了丢弃最高位的处理方法,丢弃了1之后,i的值变成了0
  • 1
  • 2
  • 3
  • 4

左移里面一个比较特殊的情况是当左移动的位数超过该数值类型的最大位数时,编译器会用左移的位数区模类型的最大位数,如

int i=1,j=0x80000000;//设int32i=i<<33;//33%32=1 左移动1位,i变成2
j=j<<33;//33%32=1 左移动1位,j变成0,最高为被丢弃
  • 1
  • 2
  • 3

总之左移就是: 丢弃最高位,0补最低位

右移

右移对符号位的处理和左移不同,对于有符号整数来说,比如int类型,右移会保持符号位不变,例如

int i = 0x80000000;
i = i >> 1; //i的值不会变成0x40000000,而会变成0xc0000000
  • 1
  • 2
  • 就是说,符号位向右移动后,正数的话补0,负数补1,也就是汇编语言中的算术右移.同样当移动的位数超过类型的长度时,会取余数,然后移动余数个位.
  • 总之,在C中,左移是逻辑/算术左移(两者完全相同),右移是算术右移,会保持符号位不变.实际应用中可以根据情况用左/右移做快速的乘/除运算,这样会比循环效率高很多.
-5>>3=-1
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1111 1111
其结果与 Math.floor((double)-5/(2*2*2)) 完全相同。

-5<<3=-40
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1101 1000 
其结果与 -5*2*2*2 完全相同。

5>>3=0
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0000
其结果与 5/(2*2*2) 完全相同。

5<<3=40
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0010 1000
其结果与 5*2*2*2 完全相同。

-5>>>3=536870911 
1111 1111 1111 1111 1111 1111 1111 1011
0001 1111 1111 1111 1111 1111 1111 1111

无论正数、负数,它们的右移、左移、无符号右移 32 位都是其本身,比如 -5<<32=-5、-5>>32=-5、-5>>>32=-5。
一个有趣的现象是,把 1 左移 31 位再右移 31 位,其结果为 -10000 0000 0000 0000 0000 0000 0000 0001
1000 0000 0000 0000 0000 0000 0000 0000
1111 1111 1111 1111 1111 1111 1111 1111

对于10进制的数字,左移一位就是在末尾加上一个0,数值变大10倍。
同理,对于二进制数字,左移一位是在末尾加上一个0,数值变大2被。
所以 x << 3x就变大 2^3 倍,就是 8*x
右移同理 

一般情况下你要乘或者是除以数字是2的次方的话都可以用的
执行速度快

猜你喜欢

转载自blog.csdn.net/qq_34793133/article/details/80180854
今日推荐