首页 > 其他分享 >二进制位运算

二进制位运算

时间:2022-08-23 23:11:11浏览次数:56  
标签:运算 二进制位 ll 二进制 int ans -- mod

二进制位运算基础及其应用:

一、基本位运算符:

1.& 按位与:(从左到右)二进制中对应位都是1则为1,否则为0;

2. | 按位或:(从左到右)二进制中对应位有一个是1则为1,否则为0

3. ^按位异或:(从左到右)二进制中对应位相同则为0,不同为1;

4. <<左移:右侧空位补0,二进制位数变化。

                   对于一个数x,x<<n等于x*2n

5. >>右移:左侧空位补符号位,二进制位数不变。

                   对于一个数x,x>>n等于x/2n

6. ~ 按位非:此运算比较复杂,在此详细解释:

    ~x等于将x的补码取反(包括符号位)后作为~x的补码,然后最终返回~x的原码

    例:

    1.对于正数8:

    ~8=-9;

    8的二进制原码:00001000-->8的补码00001000-->~8补码11110111-->~8补码-1,再取反求得原码为:10001001-->所以~8=(10001001)2=(-9)10。

    2.对于负数-3:

    ~-8=7;

    -8的二进制原码:10001000-->-8的补码11111000-->~-8补码00000111-->~-8原码即为:00000111-->所以~-8=(00000111)2=(7)10。

可得出规律:任一个数的非运算都等于它的相反数减一,包括0(~0=-1

关于位运算与二进制的实际应用:

1.求n的二进制表示中第k位(从左到右)数字是什么:

/*
1.先将第k位移到最后一位n >> k
2.看最后一位是几 & 1
*/
int bsk(int n,int k){//此函数则返回n二进制的第k位
	return n>>k&1;
}

2.判断x的二进制最后一位:x&1

//例如判断a的二进制最后一位,通过这种方式也可以判断奇偶(0则偶,1则奇)
int a=100;
cout<<(a&1)<<endl;

3.返回x的二进制最低位1出现时所对应的值(lowbit):

//lowbit返回x的二进制最低位1出现时所对应的值:
//在c++中 x & -x = x & (~x + 1)
int lowbit(int x){
	return x&-x;
}

4.上述bsk函数的应用:

#include<iostream>
using namespace std;
int bsk(int n,int k){//此函数则返回n二进制的第k位
	return n>>k&1;
}
int main(){
    //输出1024二进制的第1~9位:
	for(int i=1;i<=10;i++){
		cout<<bsk(1024,i)<<' ';
	}
	cout<<endl;
	//截取18767二进制的第3~12位并按原二进制顺序输出:
	for(int i=12;i>=3;i--){
		cout<<bsk(18767,i)<<' ';
	}
	cout<<endl;
	//输出23456的二进制:
	int top=0,b[1000];
	int t=23456;
	while(t!=0){
		b[top++]=t&1;
		t>>=1;
	}
	while(top>=0){
		cout<<b[--top];
	}
	cout<<endl;
}

5.龟速乘:

//龟速乘:(可防止数据溢出)
ll mul(ll a,ll b,ll mod=1000000000){//求a乘b,mod表示控制输出后n位(不包括前导0),则mod为1后面跟n个0
	ll ans=0;
	while(b!=0){
		if(b&1){//b的二进制位(最后一位)不为0,则进行
			ans=(ans+a)%mod;
		}
		a=(a<<1)%mod; //等价于a*2%mod
		b>>=1; 
	}
	return ans%mod;
}

6.快速幂:速度快,时间复杂度为O(logn).

ll qpow(ll a,ll b,ll mod){//求a的b次方,mod表示输出后n位(不包括前导0),则mod为1后面跟n个0
	ll ans=1;
	while(b!=0){
		if(b&1){//b的二进制位(最后一位)不为0,则进行
			ans=mul(ans,a)%mod;//这里用到了上面的龟速乘,防止数据溢出
		}
		a=mul(a,a)%mod;
		b>>=1; 
	}
	return ans%mod;
}

 快速幂和龟速乘原理都是一致的,都是利用二进制分解运算

7.lowbit的应用:

//统计二进制n中1的个数:
	int ans=0;
	int n=240;
	while(n>0){
		n-=lowbit(n);
		ans++;
	}
	cout<<ans<<endl;

  原理为:先用原数计算出lowbit(x),然后用原数减去这个数,再不断lowbit。

  这也是树状数组的实现原理。
  基于这个操作我们可以将分解出一个整数可以由哪些的2的幂相加构成。比如11110000也就是240=2^4+2^5+2^6+2^7。

以上就是二进制与位运算的全部内容了。

标签:运算,二进制位,ll,二进制,int,ans,--,mod
From: https://www.cnblogs.com/xiaotan-js/p/16618224.html

相关文章

  • python基础——变量 数据类型 运算符 格式化 if语句复习
    拓展+复习:1.input(’'你要输入的内容')--输入2.print('你要输入的内容')--输出/打印3.注释多行,单行多行注释”“”“”“''''''#ctrl+/4.变量的定义定义变量的......
  • AcWing算法基础课---第一讲基础算法---05位运算
    ###整数n的二进制数的第k位数```n>>k&1```###lowbit运算```lowbit(x)x&(~x+1)=x&(-x)```###AcWing801.二进制中1的个数```#include<iostream>usingn......
  • python基础——数据转换与运算符
    数据转换转换数据类型的作用input()接收用户输入的数据都是字符串类型,想得到整型该如何操作?转换数据类型即可,即将字符串类型转换成整型转换数据类型的函数函数说......
  • java运算符的使用
    运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。1、算术运算符2、赋值运算符3、比较运算符(关系运算符)4、逻辑运算符5、位运算符6、三元运算符  自......
  • python---运算符(1)
    1.算数运算符  代码演示:num1=10num2=3print(num1+num2)print(num1-num2)print(num1*num2)print(num1/num2)print(num1%num2)#取余,10除3余数print(num......
  • 可选链 ?. 和 空值合并运算符使用
    可选链;leta={name:'123',}letb=a?.name//条件都满足才会把a的name属性值赋给b//条件1:a是真值true//......
  • 展开运算符在数组和对象中的使用
    1.数组中使用1.1合并2个数组constarr1=[1,2,3]constarr2=[4,5,6]console.log([...arr1,...arr2])1.2求最值constarr1=[1,2,3]......
  • [HNOI2002]奶牛的运算
    题目链接Solution陈年老题了,但真是一道组合数好题。根据数学知识,加括号就相当于改变里面的符号,所以我们可以将其看为对符号的修改,问题就变为:一个长度为\(n-1\)的符号......
  • 有理数运算
    https://www.acwing.com/problem/content/description/1580/思路:这题思路并不难,但如果你傻乎乎的一种一种情况的输出,那会非常的繁琐,巧妙的利用一个函数来统一起来实现。......
  • JavaScript快速入门-04-运算符
    4运算符4.1算术运算符4.1.1概述  JavaScript提供的算术运算符如下所示:类型符号示例加法运算符+a+b减法运算符-a-b乘法运算符*a*b除......