>n;}intmain(){//leftshiftchara1=127;chara2=-1;for(inti=1;i<=8;i++)printf("%" />

位运算之左移右移运算

系统 3135 0

位运算之左移右移运算之详解

先看如下一段左移右移的代码及其结果:

代码
          
#include " stdio.h " char leftshift( char i, int n) { if (n < 0 ) return - 1 ; return i << n; } char rightshift( char i, int n) { if (n < 0 ) return - 1 ; return i >> n; } int main() { // leftshift char a1 = 127 ; char a2 = - 1 ; for ( int i = 1 ; i <= 8 ; i ++ ) printf( " %d<<%d = %d;\n " , a1, i, leftshift(a1,i)); for (i = 1 ; i <= 8 ; i ++ ) printf( " %d<<%d = %d;\n " , a2, i, leftshift(a2,i)); // rightshift a1 = 127 ; a2 = - 128 ; for (i = 1 ; i <= 8 ; i ++ ) printf( " %d>>%d = %d;\n " , a1, i, rightshift(a1,i)); for (i = 1 ; i <= 8 ; i ++ ) printf( " %d>>%d = %d;\n " , a2, i, rightshift(a2,i)); return 0 ; }

结果为:

结果
          
127 << 1 = - 2 ; 127 << 2 = - 4 ; 127 << 3 = - 8 ; 127 << 4 = - 16 ; 127 << 5 = - 32 ; 127 << 6 = - 64 ; 127 << 7 = - 128 ; 127 << 8 = 0 ; - 1 << 1 = - 2 ; - 1 << 2 = - 4 ; - 1 << 3 = - 8 ; - 1 << 4 = - 16 ; - 1 << 5 = - 32 ; - 1 << 6 = - 64 ; - 1 << 7 = - 128 ; - 1 << 8 = 0 ; 127 >> 1 = 63 ; 127 >> 2 = 31 ; 127 >> 3 = 15 ; 127 >> 4 = 7 ; 127 >> 5 = 3 ; 127 >> 6 = 1 ; 127 >> 7 = 0 ; 127 >> 8 = 0 ; - 128 >> 1 = - 64 ; - 128 >> 2 = - 32 ; - 128 >> 3 = - 16 ; - 128 >> 4 = - 8 ; - 128 >> 5 = - 4 ; - 128 >> 6 = - 2 ; - 128 >> 7 = - 1 ; - 128 >> 8 = - 1 ;

左移操作(<<)
规则:
右边空出的位用0填补
高位左移溢出则舍弃该高位。
计算机中常用补码表示数据:
数据 127,补码和原码一样:0111 1111。
左移一位: 1111 1110 -> 这个补码对应的原码为:1000 0010 对应十进制:-2
左移二位: 1111 1100 -> 这个补码对应的原码为:1000 0100 对应十进制:-4
左移三位: 1111 1000 -> 这个补码对应的原码为:1000 1000 对应十进制:-8
左移四位: 1111 0000 -> 这个补码对应的原码为:1001 0000 对应十进制:-16
左移五位: 1110 0000 -> 这个补码对应的原码为:1010 0000 对应十进制:-32
左移六位: 1100 0000 -> 这个补码对应的原码为:1100 0000 对应十进制:-64
左移七位: 1000 0000 -> 这个补码对应的原码为:1000 0000 对应十进制:-128
左移八位: 0000 0000 -> 这个补码对应的原码为:0000 0000 对应十进制:0
注:
原码到补码的计算方式:取反+1,
补码到原码的计算方式:-1再取反。
数据-1,它的原码为1000 0001,补码为1111 1111
左移一位: 1111 1110 -> 这个补码对应的原码为:1000 0010 对应十进制:-2
左移二位: 1111 1100 -> 这个补码对应的原码为:1000 0100 对应十进制:-4
左移三位: 1111 1000 -> 这个补码对应的原码为:1000 1000 对应十进制:-8
左移四位: 1111 0000 -> 这个补码对应的原码为:1001 0000 对应十进制:-16
左移五位: 1110 0000 -> 这个补码对应的原码为:1010 0000 对应十进制:-32
左移六位: 1100 0000 -> 这个补码对应的原码为:1100 0000 对应十进制:-64
左移七位: 1000 0000 -> 这个补码对应的原码为:1000 0000 对应十进制:-128
左移八位: 0000 0000 -> 这个补码对应的原码为:0000 0000 对应十进制:0
可以看出127和-1的结果完全一样。移位操作与正负数无关,它只是忠实的将所有位进行移动,补0,舍弃操作。
右移操作(>>)
规则:

左边空出的位用0或者1填补。正数用0填补,负数用1填补。注:不同的环境填补方式可能不同;

低位右移溢出则舍弃该位。

1、127的补码:0111 1111

右移一位: 0011 1111 -> 原码同补码一样 对应十进制:63

右移二位: 0001 1111 -> 原码同补码一样 对应十进制:31

右移三位: 0000 1111 -> 原码同补码一样 对应十进制:15

右移四位: 0000 0111 -> 原码同补码一样 对应十进制:7

右移五位: 0000 0011 -> 原码同补码一样 对应十进制:3

右移六位: 0000 0001 -> 原码同补码一样 对应十进制:1

右移七位: 0000 0000 -> 原码同补码一样 对应十进制:0

右移八位: 0000 0000 -> 原码同补码一样 对应十进制:0

2、-128的补码:1000 0000

右移一位: 1100 0000 -> 这个补码对应的原码为:1100 0000 对应十进制:-64

右移二位: 1110 0000 -> 这个补码对应的原码为:1010 0000 对应十进制:-32

右移三位: 1111 0000 -> 这个补码对应的原码为:1001 0000 对应十进制:-16

右移四位: 1111 1000 -> 这个补码对应的原码为:1000 1000 对应十进制:-8

右移五位: 1111 1100 -> 这个补码对应的原码为:1000 0100 对应十进制:-4

右移六位: 1111 1110 -> 这个补码对应的原码为:1000 0010 对应十进制:-2

右移七位: 1111 1111 -> 这个补码对应的原码为:1000 0001 对应十进制:-1

右移八位: 1111 1111 -> 这个补码对应的原码为:1000 0001 对应十进制:-1

常见应用
左移相当于*2,只是要注意边界问题。如char a = 65; a<<1 按照*2来算为130;但有符号char的取值范围-128~127,已经越界,多超出了3个数值,所以从-128算起的第三个数值-126才是a<<1的正确结果。
而右移相当于除以2,只是要注意移位比较多的时候结果会趋近去一个非常小的数,如上面结果中的-1,0。
其它的四种位运算:
与运算(&)
1、与0相与可清零
2、与1相与可保留原值
或运算(|)
1、与0相或可保留原值
2、与1相与可齐设1
异或运算(^)
1、与0异或保留原值
2、与1异或比特值反转
3、可通过某种算法,使用异或实现交换两个值
异或运算是有结合律的
取反(~)

位运算之左移右移运算


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论