Shift left and right shift operation rules in C language

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

shift left

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

The binary of 1 is 
000…0001 
(the number of 0s in front here is related to the number of int digits, 32-bit machine, there are 31 0s in gcc), after shifting 2 bits to the left, it becomes: 
000…0100, 
which is 10 The base is 4, so it is said that a left shift of 1 bit is relative to multiplying by 2 to the nth power (signed numbers are not applicable, because left shifts may cause changes, and the reasons are explained below)

//需要注意的一个问题是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

A special case of left shift is that when the number of bits shifted to the left exceeds the maximum number of bits of the numeric type, the compiler will use the maximum number of bits of the modulo type in the number of bits shifted to the left, such as

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

In short, the left shift is: discard the highest bit, 0 complement the lowest bit

move right

Right shift handles the sign bit differently than left shift. For signed integers, such as int types, right shift will keep the sign bit unchanged, for example

int i = 0x80000000;
i = i >> 1; //i的值不会变成0x40000000,而会变成0xc0000000
  • 1
  • 2
  • That is to say, after the sign bit is moved to the right, the positive number is filled with 0, and the negative number is filled with 1, which is the arithmetic right shift in assembly language. Similarly, when the number of bits moved exceeds the length of the type, the remainder will be taken, and then the remainder will be moved. bit.
  • In short, in C, left shift is logical/arithmetic left shift (both are exactly the same), and right shift is arithmetic right shift, which will keep the sign bit unchanged. In practical applications, left/right shift can be used for fast multiplication according to the situation / division operation, which is much more efficient than looping.
-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的次方的话都可以用的
执行速度快

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325641446&siteId=291194637