位运算:小白完全看的懂得超全位运算教程及其应用
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);
大佬们试着思考出结果评论留下答案后编译运行程序查看正确答案!
如有问题可以留言!!
以上是关于位运算:小白完全看的懂得超全位运算教程及其应用的主要内容,如果未能解决你的问题,请参考以下文章