【C++】位运算

01、目录

02、前言

今天恰逢Visual Studio 2015出了点毛病,迫于无奈之下只有卸载重装,这种比较费时间的事情,就写一篇博客叭。
整理了下思路,复习了下位运算,今天就简单聊聊它。
虽然位运算很底层,一听人说直接操作二进制,哇,这么高大上。其实,搞明白了也没啥,而且位运算的只是真的不多。我下面就直接开始吧。

03、初识位运算

其实只要了解计算机的人都或多或少知道,计算机的各种操作都是通过0和1来完成的。
没错,计算机操作的本质就是操作二进制。
而我们程序员是不可能盯着密密麻麻的二进制来编写程序的,就算你厉害,看得懂,那也不可能。
大众化的才能被人们广泛接受。

所以,某某某就通过出于这个需求的考虑,设计了一种操作二进制的规则,也就是位运算。

先来篇口诀吧!

清零取反要用与,某位置一可用或 
若要取反和交换,轻轻松松用异或 

再列举下多种语言的位运算:

含义pascalC/C++java
按位与a and ba & ba & b
按位或a or bab
按位异或a xor ba ^ ba ^ b
按位取反not a~a~a
左移a shl ba << ba << b
有符号右移a shr ba >> ba >> b
无符号右移//a >>> b

这里的pascal也是一种语言,点击此处 了解!

介绍了位运算,就继续介绍这些符号怎么用,可以达到什么效果吧!

04、位运算操作符

这里其他两种语言我不做介绍,除了第一种,Java与C/C++基本一样。
主要介绍C/C++中的位运算:

4.1 按位与

按位与,在C++中表示为 &

位运算其实只有一种情况,用竖式两位对齐计算,下面是运算结果:

代码中的例子,我写一次,后面与之大同小异。

//比如:0按位与0
int a = 0 & 0;
printf("a= %d\n",a); //result:0

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

也就是说,只有两者都为1,结果才是1,其余都是0 ——>按位与
简记:按位与,有零则零!

4.2 按位或

按位或,在C++中表示为 |

四种情况如下:

0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1

也就是说,只有两个都为0时,结果才为0,其余都是1——>按位或
简记:按位或,有壹则壹!

4.3 按位异或

按位异或,在C++中为 ^ (这里初学者容易搞成乘方,注意哈!)

四种情况如下:

0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0

按位与或的情况很特殊,很容易迷惑人,这跟乘方实在太像了,不过这里我们还是总结下:相同是0,不同则是1——>按位与或
简记:同零异壹!

4.4 按位取反

按位取反,在C++中为 ~

这里情况分两种:

~0 = 1
~1 = 0

用得不多,理解就好,其实我看见有一篇博客讨论按位取反的时候讨论了一下大于0,小于0的情况,这里我说说我的理解,完全没必要,既然位运算的对象是二进制,就只有0和1,没必要脱离主题。

按位取反,我觉得是最好记的,相反就ok,如果是1,则按位取反为0,若是0,则按位取反为1——>按位取反
简记:本身取反!(真假相反)

4.5 左移

左移,在C++中为 <<

不知道怎么表达,先看例子叭!

比如: 8 左移 3bit(位)

//首先8转换为2进制
0000 1000

8 << 3;  //整体向左移动3位

0100 0000 //当然这里我的写法优化了下,原型如下:

000 0100 0000 //为使形式好看点,所以上面做了写法优化,右移大同小异,下面不多写

当然这是二进制表示,如果要用数学表示出来即是:
a == 8
n == 2

a << n === a * 2^n 这里的^不是按位与或,而是乘方

记住:左移多少位,右边补多少位,填充数为0即可。

4.6 右移

右移,在C++中为 >>

将操作数的所有位向右平移指定的位数。向右移动了几位,左面补几个 0,向右位移的部分舍弃。

比如 6 右移 1 位

0000 0110 >> 1

结果为:0000 0011

右移n位相当于除以2的n次方

当然我没有提符号右移与无符号右移。那是涉及到负数哈。
其实也是一样的。符号位为最高位,比如:

-10怎么表示:
1000 1010 这就是-10的二进制表示。最高位即,最左边位为1,就是负数,为0就是正数。
学过补码都都应该懂这句话的意思。

补码>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>看这里 补码百科

而负数跟有符号和无符号怎么回事呢?
就是有符号,符号位你右移不能消掉。懂吧,左移跟正数一样。考虑一下这种情况就是上面提到的,我这里提一下规则,举个例子。

  • 负数的右移:负数右移的话,由于要保持它是负数,所以负数的二进制的右边补1。如果一直右移的话,最后就就变成0xFFFFFFFF 即-1
    如: -4>>1 为-2 ;-4>>2为-1
  • 负数的左移:跟正整数左移一样,右边补0,一直左移的话,最后就是0啦。-2<<2 为-4 ; -2<<31为0

05、总结

关于位运算,其实要想搞得很清楚,建议还是搞一下计算机的补码、反码、原码。
值得一提的是:计算机始终是保存的补码。
然后后面如果有时间,我会抽空聊聊这些基础,当然,这在计算机结构专栏里面,我会详细说明。

版权声明:转载请注明出处,谢谢!

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cain Xcy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值