简述位运算符

本文深入探讨了C/C++中的位运算符,包括按位与(&)、按位或(|)、按位取反(~)、异或(^)以及左移(<<)、右移(>>)和无符号右移(>>>)。详细解析了这些运算符在处理正数和负数时的规则,通过实例展示了运算过程,帮助理解位运算在二进制层面的操作。
摘要由CSDN通过智能技术生成

简谈位运算符

  • 前言:读者需要对源码,补码有一定了解,在此不过多讲解

一、& 按位与运算符

int foo = 10 & 7;
printf("%d", foo); // 2

规则:将左右两边的表达式每一位进行逻辑与,如果是负数,先转换为正数的补码,进行逻辑与

二、|按位或运算符

int bar = 10 | 15
printf("%d", bar); // 15

将左右两边的表达式每一位进行逻辑或,如果是负数,先转为负数的补码,进行逻辑或

上面这两个运算符,只需单独将它们的二进制位,每一位进行运算即可,考虑负数的问题,先将负数的二进制求出,进行运算,运算结果就是就是该负数的绝对值,再将绝对值取反加1,拿到的就是按位或后的值。

如下代码

int bar = 10 | -7

10的 二进制代码是 -> 1010

-7的 二进制代码是 -> 先求正7 0111 取反加1,就是负数的二进制代码 1001

将这两个值进行相或运算, 1 1011 开头的"1"代表这是一个负数,“”1 1011“”这是一个负数的绝对值! 前面省略28个1,只用1代表是负数,int类型存储是32位

再将该补码取反1加即可得到最后或运算的结果
即:1 0100 + 1 - > 1 0101 == -5

同理 按位与和上面解释原理一样

但下面这两个运算符不那么轻松

三、~ 按位取反

将 “~” 右侧的表达式进行每一位取反

取反规则:

负数:先将该负数正数的二进制代码以补码的形式求出

该负数正数的二进制代码取反加1即是该负数的二进制代码

如:-3的二进制码是 +3 0011 取反加1后的结果 1101

拿到二进制码之后(该码是该负数以补码的形式存储的二进制代码)再取反,得到的二进制代码就是~后的数(负数的最高位是1,但经过取反之后为0,所得结果一定是正数)

正数: 取出表达式的二进制码,将每一位取反(此时最高位是1,代表是一个负数),所以需要取反得到该负数的绝对值(正数的结果一定是一个负数)

如:2的二进制码是 +2 0010 需要每一位取反结果为 1101(最高位是1,所以需要取反拿到这个负数二进制码的绝对值)
0010 + 1 == 0011 该数是一个负数结果为 -3

规则:如果是正数那么得到的结果是负数 + 1的值, 如果是负数那么得到的结果是正数 - 1的值

读者可以不追求底层原理,只求结果

四、^ 异或运算符

int foo = 2 ^ 7; // 双方正数
int bar = -2 ^ 7; // 一方为正一方为负
int mul = -7 ^ -2; // 双方负数

规则:

1、双方正数

当两边都是正数的时候,直接将倆数的二进制代码按位异或即可:
相同为0,不同为1

如:2 ^ 5
"2"的二进制为 0010 "5"的二进制为0101 相异或后为0111 结果为7

2、一方为正一方为负

当有一方为负数时,负数的一方先进行取反加1,求出该负数的二进制码,两方再进行异或,所得结果是一个负数,将这个负二进制码,进行逆运算(次码是源码,需要进行逆运算得到补码形式的二进制码,得到该负数的值)

如:-2 ^ 7
"-2"的二进制码 为 1101 "7"的二进制码 为 0111
所得结果为 1 1001 (前面的一省略28位,用一位表示该二进制码表示一个负数的绝对值)
再逆运算 -> 先减一 再去反,拿到的结果为 1001 - 1 == 1000
取反后 0111 由于是一个负数所以,结果是 -7。

3、双方负数

次用法与第一种类似,先将负数二进制码求出,进行异或,所得结果就是两数异或后的结果。

如:-2 ^ -5;
"-2"的二进制码为1110 "-5"的二进制码为1011 异或所得值为 0101所以所得结果 5;

五、<< 按位左移

规则:左移n位相当于将该数字的二进制乘于左移次方数

正数:直接左移,将二进制码成于左移次方
负数:和左移一样,只是加了负号

如:2 << 2
0010 乘以2的n次方 1000 将1向左移,右边补0

如:-2 << 2
只是加了符号,并不会拿负数的二进制码去左移。

六、>> 按位右移

规则: 右移n位相当于将该数字的二进制除以右移次方数

正数:直接右移,将二进制码除以右移次方,最高位是1补1,最高位是0补0
负数: 和右移一样,只是加了负号

如:2 >> 2
0010 除以2的n次方 1000 将1向右移,左边补0

如:-2 >> 2
只是加了符号,并不会拿负数的二进制码去右移。

七、>>> 按位右移(左边补1)

规则:功能与 >> 一样,只是强制左边补1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值