常用位运算

87 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、常见的位运算

1、按位与(&)

运算规则:0&0=0;  0&1=0;   1&0=0;    1&1=1; 即:两位同时为“1”,结果才为“1”,否则为0

例如:3&5  即 0000 0011& 0000 0101 = 00000001  因此,3&5的值得1。

2、按位或(|)

运算规则:0|0=0;  0|1=1;  1|0=1;   1|1=1;即 :两个相同位只要有一个为1,其值为1。

例如:3|5 即 00000011 | 0000 0101 = 00000111  因此,3|5的值得7。

3、按位异或(^)

运算规则:0^0=0;  0^1=1;  1^0=1;   1^1=0;即:两个同一位上的数字相同,则该位结果为1,否则为0。

例如:3|5 即 00000011 ^ 0000 0101 = 00000110  因此,3|5的值得6。

4、按位取反(~)

运算规则:~0=1,~1=0;即:对1取反得0,对0取反得1。

例如:3 即(00000011)=(11111100)

5、左移运算符(<<)

a<<b

将a各二进制位全部左移b位后得到的值,左移越界丢弃,低位补0。

作用:实际上,左移一位等于乘以2

例如:9<<4 

9的二进制:0000 0000 0000 0000 0000 1001

将该二进制左移4位:0000 0000 0000 0000 1001 0000,因此9<<4=144。

 

6、右移运算符(<<)

a>>b

将a各二进制位全部右移b位后得到的值。溢出最右边的值就被丢弃。

对于有符号数大多数编译器规定:右移时原符号位为1,右移则补1,原符号位为0,右移就补0

作用:右移n位相当于除2^n次方,但有可能除不尽,取整。

例如:9>>2 

9的二进制:0000 0000 0000 0000 0000 1001

将该二进制右移2位:0000 0000 0000 0000 0000 0010,因此9>>2=2。

在这里插入图片描述

#include<iostream>

using namespace std;
int main()
{
	int n = 10;

	for(int i = 3; i >= 0; i--)
		cout << (n >> i & 1);//&是“与”操作
	return 0;
}

lowbit是树状数组的一个基本操作,返回x的最后一位1 在这里插入图片描述 在这里插入图片描述 应用:可以统计x里面1的个数 在这里插入图片描述

二进制中1的个数

题目:给定一个长度为n的数列,请你求出数列中每个数的二进制表示中1的个数。

输入格式

第一行包含整数n。

第二行包含n个整数,表示整个数列。

输出格式

共一行,包含n个整数,其中的第i个数表示数列中的第i个数的二进制表示中1的个数。

数据范围

1n1000001≤n ≤100000,

0数列中元素的值1090≤数列中元素的值≤10^9

输入样例:

5 1 2 3 4 5

输出样例:

1 1 2 1 2

#include<iostream>

using namespace std;

int lowbit(int x)
{
	return x & -x;
}
int main()
{
	int n;
	cin >> n;
	while(n--)
	{
		int x;
		cin >> x;
		int res = 0;
		while(x)
		{
			x -= lowbit(x);
			res++;
		}
		cout << res << ' ';
	}
	return 0;
}