蓝桥集训之位运算和相关函数
Posted MangataTS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥集训之位运算和相关函数相关的知识,希望对你有一定的参考价值。
原码、反码、补码
https://blog.csdn.net/m0_46201544/article/details/121818968?spm=1001.2014.3001.5501
计组的内容,可以去搜一下先了解
位运算
&按位与
定义
如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
举例
对于这样两个数:3、5,我们先将其转化为为二进制:
3 = ( 0011 ) 2 3=(0011)_2 3=(0011)2
5 = ( 0101 ) 2 5=(0101)_2 5=(0101)2
那么我们对其进行按照位与操作可得: ( 0001 ) 2 (0001)_2 (0001)2也就是1
代码实现:
#include<stdio.h>
int main()
int a = 3,b = 5;
printf("a&b = %d\\n",a&b);
return 0;
| 按位或
定义
两个相应的二进制位中只要有一个为1,该位的结果值为1
举例
对于这样两个数:3、5,我们先将其转化为为二进制:
3 = ( 0011 ) 2 3=(0011)_2 3=(0011)2
5 = ( 0101 ) 2 5=(0101)_2 5=(0101)2
那么我们对其进行按照位或操作可得: ( 0111 ) 2 (0111)_2 (0111)2也就是7
代码实现:
#include<stdio.h>
int main()
int a = 3,b = 5;
printf("a|b = %d\\n",a|b);
return 0;
^ 按位异或
定义
若参加运算的两个二进制位值相同则为0,否则为1
举例
对于这样两个数:3、5,我们先将其转化为为二进制:
3 = ( 0011 ) 2 3=(0011)_2 3=(0011)2
5 = ( 0101 ) 2 5=(0101)_2 5=(0101)2
那么我们对其进行按照位或操作可得: ( 0110 ) 2 (0110)_2 (0110)2也就是6
代码实现:
#include<stdio.h>
int main()
int a = 3,b = 5;
printf("a^b = %d\\n",a^b);
return 0;
~ 取反
定义
~是一元运算符,用于求整数的二进制补码,即分别将操作数各二进制位上的1变为0,0变为1。
举例
对于一个数字1,我们先对其转化为二进制并转化为补码:
(
00000001
)
H
(00000001)_H
(00000001)H然后取反,那么可以得到:
(
F
F
F
F
F
F
F
E
)
H
(FFFFFFFE)_H
(FFFFFFFE)H,然后我们再求该数的原码则得:-2
代码实现:
#include<stdio.h>
int main()
int a = 1;
printf("~a = %d",~a);
return 0;
<< 左移
定义
用来将一个数的各二进制位全部左移N位,右补0
效果等价将该数乘二
举例
#include<stdio.h>
int main()
int a = 1;
printf("a<<2 = %d",a<<2);
return 0;
>> 右移
定义
将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0
效果等价将该数除二
举例
#include<stdio.h>
int main()
int a = 7;
printf("a>>2 = %d",a>>1);
return 0;
一些应用
例如:
将该数的某一位设置为1
我们通过左移和或位运算即可将该数的某一位设置为1,或者是判断是否为1
eg:x|(1<<10)
:将从右往左第十个位置设为1
两个相同的异或值为0
如标题,可以和我们上次学的前缀和结合起来,并且根据这个性质我们能写出不需要零时变量数的SWAP函数
通过&运算判断数n是否为奇数
我们将n和1进行位与操作就能判断,因为奇数和偶数我们只需要判断最后一位是否为1即可
if(n&1)
puts("奇数");
else
puts("偶数");
取int型变量a的第k位 ( k = 0 , 1 , 2 … … s i z e o f ( i n t ) ) (k=0,1,2……sizeof(int)) (k=0,1,2……sizeof(int))
a>>k&1
更多技巧请参考这篇文章:
https://zhuanlan.zhihu.com/p/54946559
位运算相关函数
__builtin_popcount(unsigned int n)
该函数时判断n的二进制中有多少个1
eg:
int n = 15; //二进制为1111
cout<<__builtin_popcount(n)<<endl;//输出4
__builtin_parity(unsigned int n)
该函数是判断n的二进制中1的个数的奇偶性
eg:
int n = 15;//二进制为1111
int m = 7;//111
cout<<__builtin_parity(n)<<endl;//偶数个,输出0
cout<<__builtin_parity(m)<<endl;//奇数个,输出1
__builtin_ffs(unsigned int n)
该函数判断n的二进制末尾最后一个1的位置,从一开始
eg:
int n = 1;//1
int m = 8;//1000
cout<<__builtin_ffs(n)<<endl;//输出1
cout<<__builtin_ffs(m)<<endl;//输出4
__builtin_ctz(unsigned int n)
该函数判断n的二进制末尾后面0的个数,当n为0时,和n的类型有关
eg:
int n = 1;//1
int m = 8;//1000
cout<<__builtin_ctzll(n)<<endl;//输出0
cout<<__builtin_ctz(m)<<endl;//输出3
__builtin_clz (unsigned int x)
该函数判断n的二进制前导的0的个数。
eg:
#include<stdio.h>
int main()
int a = 1<<30;
printf("%d\\n",__builtin_clz (a));//输出1
return 0;
以上是关于蓝桥集训之位运算和相关函数的主要内容,如果未能解决你的问题,请参考以下文章