蓝桥集训之位运算和相关函数

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,2sizeof(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;

以上是关于蓝桥集训之位运算和相关函数的主要内容,如果未能解决你的问题,请参考以下文章

C程序设计之位运算

shell编程之位运算符

Leetcode刷题之位运算(Java)

Leetcode刷题之位运算(Java)

C之位运算(十五)

PHP之位运算符