位运算:小白完全看的懂得超全位运算教程及其应用

Posted 「已注销」

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位运算:小白完全看的懂得超全位运算教程及其应用相关的知识,希望对你有一定的参考价值。

文章目录

位运算

1.基本概念

位运算:用于对整数类型(int , char , long 等) 变量中的某一位(bit), 或者若干位进行操作.

“&”按位与(双目)
“|”按位或(双目)
“^”按位异或(双目)
“~”按位非(取反)(单目)
“<<”左移(双目)
“>>”右移(双目)

2.按位与"&"

概念:

皆一则一,否则为零(二进制位)

将参与运算的两个操作数对应的二进制进行操作,只有对应的两个二进制位均为1时,结果的对应二进制才为1,否则为0.

用法1:

按位与通常用来将某变量中的某些位 置0且保留其他位不变.

例: 将 int型变量n的低8位全置成0,而其余位不变,则可以执行:

n = n & 0xffffff00;
// 或
n &= 0xffffff00;

将 0xffffff00 转成2进制表示 : 1111 1111 1111 1111 1111 1111 0000 0000

低8位都是0 ,其余都是1. 因为0’与’任何数都是0, 1’与’0则0,1’与’1则1;

因此可以通过’&’ 给任意位置 置为零

如果n为short类型,则需执行:

n &= 0xff00;
用法2:

判断int类型变量n的某一位是否是1 (从又向左,从0开始数)

例如: 通过以下代码则可以判断第7位是否为1

n & 0x80;  // 若果表达式的值等于0x80, 则第7位为1

将0x80 转成2进制表示: 1000 0000

可以看到除了第7位是1,其余位都为0

同理可知, n第7位如果是1表达式结果第7位便是1,如果n第7位如果是0表达式结果第7位便是0.

3.按位或"|"

概念:

皆零则零,否则为一(二进制位)

将参与运算的两操作数各对应的二进制位进行或操作,只有对应的两个二进位都为0时,结果的对应二进制位才是0,否则为1。

计算表达式: 21|18的值 :

21: 0000 0000 0000 0000 0000 0000 0001 0101

18: 0000 0000 0000 0000 0000 0000 0001 0010

21|18: 0000 0000 0000 0000 0000 0000 0001 0111 (23)

21:0000 0000 0000 0000 0000 0000 0001 0101
18:0000 0000 0000 0000 0000 0000 0001 0010
21|18:0000 0000 0000 0000 0000 0000 0001 0111 (23)
用法1:

按位或通常用来将某变量中的某些位 置1且保留其他位不变.

例: 将int类型变量n的低八位全部置成1,而且其余位不变,可执行:

n |= 0xff;

将0xff 转成2进制表示: 1111 1111

1 无论 “|” 0 还是 “|” 1, 结果都为1

4.按位异或"^"

概念:

不同则1,相同则0(二进制位)

将参与运算的两个操作数各对应的进制位进行异或操作, 即只有对应的两个二进制位不同时,结果的对应二进制位才是1, 否则为0 .

21:0000 0000 0000 0000 0000 0000 0001 0101
18:0000 0000 0000 0000 0000 0000 0001 0010
21^18:0000 0000 0000 0000 0000 0000 0000 0111 (23)
用法1:

按位异或运算常用来将某变量中的某些位取反, 且保留其他位不变.

例: 将int类型变量n的低8位取反, 而其余位不变,则可以执行:

n ^= 0xff;

将0xff 转成2进制表示: 1111 1111

如果n当前位为 1 , 因为1和1相同 , 则1^1=0

如果n当前位为 0 , 因为1和0不同 , 则1^0=1

便达到了取反的目的

性质:

如果 a^b=c, 那么就有 c^b = a 以及c^a = b. (穷举法可证)

通过此规律可以用于简单的加密解密.

原文a 通过秘钥b加密成密文c , 密文c通过秘钥b 解密成原文a.

通过这个性质我们也可以用于整形变量之间的数据交换

用法2:

整形变量之间的数据交换;

例: (自己试着思考原因,然后继续观看下面文字内容)

int a = 5, b = 7;
a = a ^ b;
b = a ^ b;
a = a ^ b;

即实现了a,b值的交换. 穷举法可证

理解实现原理:

int a = 5, b = 7;//现在假设一个变量c,使得a^b=c;
a = a ^ b;       //此时把c的值赋值给了a,那么a == c;
b = a ^ b;       //因为a的值已经是最初c的值,a^b其实就等价于最初c的值^b,也就变回了a,并赋值给了b.
a = a ^ b;       //此时a里面是最初的c,b里面是最初的a,那么a^b等价于最初的c^最初的a,也就是最初的b.并赋值                    给变量a;

5.按位非"~"

概念:

为0变1,为1变0(二进制位)

按位非运算符"~"是单目运算符. 其功能是将操作数中的二进制位0变1,1变0;

21:0000 0000 0000 0000 0000 0000 0001 0101
~21:1111 1111 1111 1111 1111 1111 1110 1010
用法:

用法就是取反…(全部取反,单个位取反用按位或)

6.左移运算符"<<"

概念:

表达式: a << b 的值是:

将a各二进制位全部左移b位后得到的值. 左移时,高位丢弃, 低位补0. a 的值不因运算而改变(如要改变a = a<<b ).

例: 9 << 4

将 9 和 4 转成二进制形式:(这里为了突出不用表格了)

9 : 0000 0000 0000 0000 0000 0000 0000 1001

9 << 4 : 0000 0000 0000 0000 0000 0000 1001 0000

即为十进制的144.

规律+用法1:

左移1位, 就等于乘以2, 左移n位, 就等于乘以 2的n次方 .

左移的操作比乘法运算速度快很多(如果是2的次幂运算可以通过位运算来实现)

7.右移运算符">>"

概念:

表达式: a >> b的值是:

将a各二进制位全部右移b位后得到的值. 右移时,移出最右边的位就被丢弃. a 的值不因运算而改变

对于有负号的数,如long, int, short, char 类型的变量, 在右移时, 符号位(及最高位) 将一起移动, 并且大多数c/c++编译器规定, 如果原符号位为1, 则右移最高位就补充1 ,原符号位为0, 则右移时高位就补充0.

规律+用法1:

右移n位, 就相当于左操作数除以2的n次方, 并且将结果往小里取整.

25 >> 4 = -2等价于-25/16并向小取整, 由于是负数所以结果为-2
-2 >> 4 = -1等价于-2/16并向小取整,由于是负数所以结果为-1
18 >> 4= 1等价于18/16并向小取整,正数,结果为1

8.检验学习成果

#include<stdio.h>
int main()

	int n1 = 15;
	short n2 = -15;
	unsigned short n3 = 0xffe0;
	char c = 15;
	n1 = n1 >> 2;
	n2 >>= 3;
	n3 >>= 4;
	c >>= 3;
	printf("n1=%d, n2=%x, n3=%x, c=%x",n1,n2,n3,c);

大佬们试着思考出结果评论留下答案后编译运行程序查看正确答案!

如有问题可以留言!!

以上是关于位运算:小白完全看的懂得超全位运算教程及其应用的主要内容,如果未能解决你的问题,请参考以下文章

2020超全python中常用的运算符集合_逻辑教育

转PHP 位运算应用口诀

C++重载双目运算符

C++重载双目运算符

JAVA 二进制基础

Java 运算符,条件结构小总结