当前位置: 首页 > article >正文

位运算与操作符应用

一.二进制与进制转化

1.概念解析

我们常常能听见2进制,8进制,16进制这些讲法。他们都是数值的不同表达形式。根据不同的进制大小有着不同的权重比例。我们生活中常用的是10进制数,也就是逢10进1,由此推理至其他进制。例如2进制就是逢2进1。

2.进制转化

(1)10进制转化为2进制

如图将10进制的数不断对进制数进行取模,之后在将数除等原数,周而复始,最后将输出数导致就是原数转换的进制数。

 (2)2进制转8进制

8进制中每一位都是0~7中的数字,0~7的数字各自写成2进制位最多有3个就足够了。所以我们将二进制位转换时,每次只需3位3位的进行转化。

(3)2进制转16进制

与上文同理,16进制位是由0~9,A~F直接的数组成的,用2进制表示最多只有4位。

 3.相关技巧与用法

例如给定x进制,x进制形式的数s,要将其转换为z进制形式。

思路为先将x进制的数s转化为10进制形式,再将该数转化为z进制形式。

将x进制的s转化为10进制形式有两种方法:

(1)逐位相乘法

int main()
{
	int x;
	int i = 0;
	string s;
	int ret = 0;
	cin >> x >> s;
	int n = s.size() - 1;
	while (n >= 0)
	{
		if (s[n] <= '9')
		{
			ret += (s[n--] - '0') * pow(x, i);
		}
		else
		{
			ret += (s[n--] - 'A' + 10) * pow(x, i);
		}
		i++;
	}
	cout << ret;
	return 0;
}

将每一位的数乘对应的权重转化为10进制相加。

(2)库函数调用

#include <string>
int main()
{
	int x;
	string s;
	cin >> x >> s;
	int ret = stoi(s, nullptr, x);
	cout << ret;
	return 0;
}

这里调用了stoi函数(string  to  int),将字符串转换为int形式,有三个参数,stoi(const string& str, size_t* idx = 0, int base = 10);。第一个参数为需要转化的字符串,第二个是一个指针,指向停止转化的字符;第三个参数是需要转换的进制(默认情况为10进制)。

在这里我们将字符串s转化为x进制。

(3)将10进制转化为z进制

string s = "0123456789ABCDEF";

void print(int ret, int m)
{
	if (ret > m)
	{
		print(ret / m, m);
	}
	cout << s[ret % m];
}

这里我们将10进制数设置为ret,需要转换的进制为m进制。我们使用一个递归,参照上面的(10进制转化为2进制的思路)。

二.位运算

1.概念解析

这里就做一些简单的介绍,重点内容在于后序的运用方法。

(1)左移右移操作符

最高的符号位不变,左移将二进制数整体左移动一位右边补0;右移将二进制整体右移一位,此时分为两种情况。如果是逻辑右移则左边用0进行填充,若是算术右移则左边用符号位进行填充。

(2)&(按位与)  |(按位或)  ^(按位异或)  ~(按位取反)

例a&b当a与b二进制位上都为1,得到的结果为1,否则为0。

例a|b当a与b二进制位上有1则为1,否则为0。

例a^b当a与b二进制位上相同则为0,不相同则为1。

例~a将1变为0,将0变为1。

这里有个小tips:

所有的二进制操作都是先转化为补码的形式展开的,正数的原码反码补码都相同,负数将原码取反加1(符号位不变)得到的就是补码。

2.位运算的应用

(1)保留二进制位中的指定位

 有时候我们希望取出二进制中的某一位,使其他位变为0。我们只需要将对应的位进行(x&m)处理。

 (2)获取二进制中的指定位

当我们需要获取⼀个整数 x 的⼆进制中第 i 位(从低到⾼,以最低位为第 0 位是 1 还是 0 的时
候,我们可以对 x 做这样的运算: (x >> i) & 1 ,如果结果是 0 ,表⽰第 i 位是 0 ,如果结果是 1 ,表⽰第 i 位是 1 。

(3)将指定二进制位设置为1

设置 x ⼆进制中的某 1 位,也就是将 x ⼆进制中的第 i 位(从低到⾼,以最低位为第 0 位置为 1 ,则可以进⾏下⾯的运算: x |= (1<<i) ;

 (4)将指定二进制位设置为0

将⼀个整数 x 的⼆进制表⽰中的某 1 位设置为 0 ,其余位置保留原值。也就是将 x 二进制中的第 i 位(从低到⾼,以最低位为第 0 位)置为 0 ,其他位保持不变,则可以进⾏下⾯的运算: x &= ~(1<<i)

我们需要对指定位置设置为0,只需要对该位进行&1处理,而其他位需要&0处理。所以我们先将1移动到要置为0的位置,再按位取反,这样就只有该位得到0其余位都为1。

 

(5)反转指定二进制位

使用一个数m,使得m的二进制位中的第i位为1其余设置为0,然后将(x^m)得到反转后的值。

由于按位取反中,若原数第i位为1,相同异或取反后变为0,若原数为0,与1异或取反后为1。

 (6)将二进制位最右边的1变为0

我们可以使用x  &(x-1)的方法x - 1让有1的最低的一位变为了0,而其他位不会改变。将其进行&,就可以消去最右边的那一位1。

我们可以通过 x  &(x-1)的计算消除一位1,那么如果我们对一个数不断的进行消除1的操作,套上一个循环,就能计算出这个二进制数中1的个数。

一些其他用途:

这种思路有一个专有名词叫做位图(bitmap)。位图是数据结构操作系统常用的数据结构,他可以高效的快速释放资源 

(7)只保留二进制位中最右边的1

有时候,我们需要将⼀个整数 x 的⼆进制表⽰中最右边的 1 保留下来,其他位都置为 0 ,那么 x
&(-x)   就可以得到想要的数字。

(8)异或的巧用

相同的两个数异或的结果为0;0与任何数x异或的结果为x;同时异或满足交换律a^b^a == a^a^b;


http://www.kler.cn/a/460215.html

相关文章:

  • Px4 V2.4.8飞控Mavlink命令控制说明
  • 前端路由layout布局处理以及菜单交互(三)
  • USB射频微波功率计的功能与优势-盛铂科技
  • 基本算法——回归
  • 【QT】实现RestFul接口
  • 基于C语言的卡丁车管理系统【控制台应用程序】
  • Element plus 的 upload 组件实现自定义上传
  • 为什么要用ZGC
  • rocketmq5源码系列--(二)--生产者发送消息
  • Java基础(五): 案例练习;
  • 2024年度AI与科技突破:量子计算引领创新浪潮
  • 实战设计模式之策略模式
  • 操作系统(26)数据一致性控制
  • 计算机网络•自顶向下方法:网络层介绍、路由器的组成
  • 网工日记:FTP两种工作模式的区别
  • dockerfile 安装 Python 依赖,修改为国内的镜像源
  • [react]小技巧, ts如何声明点击事件的类型
  • 快速了解开源日志框架log4net:灵活记录应用程序日志信息的利器
  • 《代码随想录》Day20打卡!
  • 使用亚马逊针对 PyTorch 和 MinIO 的 S3 连接器实现可迭代式数据集
  • 深入探讨 Nginx 性能优化:从基础到高级的最佳实践
  • 活动预告 | Microsoft Power Platform 在线技术公开课:实现业务流程自动化
  • 机器人革新!ModbusTCP转CCLINKIE网关揭秘
  • torch.nn.Sequential的用法
  • Markov test笔记
  • 对于爬虫的配置和管理,涉及到的模块和功能主要包括