C++学习进阶:二进制与位运算

目录

1.进制与原反补码

2.位运算

2.1.按位与

2.2.按位或

2.3.异或 

2.4.取反

2.5.移位

3.部分面试题

3.1.不创建新的变量,实现两个变量的交换

3.2.求一个整数存储在内存中二进制中1的个数 


这一部分本来是C语言的内容,当学习位图时,发现这一部分的只是有点欠缺,所以恶补了一下,望周知!!!

1.进制与原反补码

我们先用几个例子来进行学习:

  • 123(10) = 1*10^2 + 2*10^1 + 3*10^0 
  • 111(2) = 7 (10)

这就是进制

我们知道在C语言中,一个整型的大小是4个字节,一个字节是8个比特位,一个bit对应0或者1

所以对于数字7 :

// 7
// 00000000 00000000 00000111 -原码
// 00000000 00000000 00000111 -反码
// 00000000 00000000 00000111 -补码

对于正整数来说,我们通过10进制来找到二进制,写成32位这时就是原码,而正整数的原反补码是一样的。

(注意32位的整型,第一位的0代表正数,1代表负数,这个位置叫做符号位)

那么数字-7呢?

// -7
// 10000000 00000000 00000111 -原码		因为是负数第一位符号位为1
// 11111111 11111111 11111000 -反码		反码通过原码符号位不变,其他位按位取反
// 11111111 11111111 11111001 -补码		补码等于反码加1

 这里我们发现跟正整数有较大的区别


整数在内存中以二进制的补码形式存储 ,操作也是通过二进制的补码形式,最终转换为10进制

2.位运算

基本规则:

接下来我们按顺序来研究这几个位运算操作!!!

 2.1.按位与

当 位运算 对应位置 均为1时 才是1。

// 按位与

0 & 0 = 0;
1 & 0 = 0;
0 & 1 = 0;
1 & 1 = 1;

0111 & 0101 = 0101

 2.2.按位或

只要 对应位为1,那么都是1 

// 按位或

0 | 0 = 0;
1 | 0 = 1;
0 | 1 = 1;
1 | 1 = 1;

0110 | 0101 = 0111

2.3.异或 

相同为0,不同为1

// 异或

0 ^ 0 = 0;
1 ^ 0 = 1;
0 ^ 1 = 1;
1 ^ 1 = 0;

0110 ^ 0101 = 0011

2.4.取反

位置为0变成1,位置为1变成0

// 取反

~0011 = 1100
~1100 = 0011

2.5.移位

  1. 左移(<<):将一个二进制数的所有位向左移动指定的位数。左移操作会在右侧添加0,并丢弃左侧超出指定位数的位。左移操作可以看作是将一个数乘以2的指定次幂。

  2. 右移(>>):将一个二进制数的所有位向右移动指定的位数。右移操作会在左侧添加0或者符号位,并丢弃右侧超出指定位数的位。右移操作可以看作是将一个数除以2的指定次幂。

例如,对于二进制数1010,进行左移和右移操作:

  • 左移2位(1010 << 2):结果为101000,相当于将1010乘以2的2次幂(4),即40。
  • 右移1位(1010 >> 1):结果为0101,相当于将1010除以2的1次幂(2),即5。
  • 左移n位,原二进制对应的10进制数乘以2^n次方
  • 右移n位,原二进制数对应10进制除以2^n次方

注意这个操作的二进制数是原数据的“补码”!!!

// 例如
// int a = 7;
// int b = a << 1;
// 00000000 00000000 00000111 7的补码
// 00000000 00000000 00001110 左移后的7的补码
// 00000000 00000000 00001110 左移后的原码 大小为14(10)

当我们对int a = -7进行左移时,我们就要进行原反补码的转换了……

另外,右移操作符分为两种情况

  • 算术移位:丢弃右边位,左边空缺位填原本的符号位
  • 逻辑移位:丢弃右边位,左边空缺填补0
// 将7左移
//   00000000 00000000 00000111
// 0 00000000 00000000 0000111 0  左移 左边删去一位 右边补0


将7右移
//   00000000 00000000 00000111
//  0 0000000 00000000 00000011 1  右移 左边补0或1 右边删去一位

 注意:

  • 左移的本质为由低地址向高地址,而不是单纯的向左移动。
  • 右移是从高地址往低地址

这里因为计算机分为大端机和小端机原因,他们左移的逻辑不同。

3.部分面试题

3.1.不创建新的变量,实现两个变量的交换

void swap(int &a, int &b)
{
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
}

 这里的原理:

  • 对于任意的整数num,恒存在 num 异或 num = 0
  • 任何num恒存在:num 异或 0 等于num

总结一下就是异或就有交换律和结合率

接下来我们用实际数据来显示:

int a = 5;    // 0101
int b = 3;    // 0011
a = a ^ b;    // a = 0101 ^ 0011 = 0110
b = a ^ b;    // b = 0110 ^ 0011 = 0101 = 3
a = a ^ b;    // a = 0110 ^ 0101 = 0011 = 5

// 我们用10进制
// a = 5 ^ 3;
// b = 5 ^ 3 ^ 3 = 5
// a = 5 ^ 3 ^ 5 = 3

3.2.求一个整数存储在内存中二进制中1的个数 

int countFunc(int a)
{
	int count = 0;
	int array[32] = { 0 };
	// 核心逻辑
	for (int i = 31; i > 0; i--)
	{
		if ((a & 1) == 1)
		{
			count++;
			array[i] = 1;
		}
		a = (a >> 1);
	}
	// 打印这个二进制数
	for (int i = 0; i < 32; i++)
	{
		if (i % 8 == 0 && i > 0)
			cout << " ";

		cout << array[i];
	}
	cout << endl;
	return count;
}

原理:

  • 如果一个数num的二进制最后一位为1,那么 num&1 = 1,否则为0
  • 我们判断一个数有多少个1,就是不断的挪动这个数二进制的每一个位置,不断&1

总结一下我们就只需要不断的判断与1是否为1,是的话就计数,每次循环结束前,右移一位

 实际数据:

// a = 5
// 00000000 00000000 00000101

// 1
// 00000000 00000000 00000001

// a & 1 = 1
// 00000000 00000000 00000001  

// a = (a>>1)
// 00000000 00000000 00000010

// a & 1 = 0
// 00000000 00000000 00000000  

 3.3.有40亿个无序且不重复的unsigned int的整数,如何快速判断这个数是否在那40亿个数当中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/535275.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

期货分账户软件|程序化软件|风控软件|资产管理软件开发用到哪些技术?

期货/股票资管分仓软件分账户系统APP的开发涉及多个技术领域&#xff0c;以确保软件的功能性、安全性和易用性。以下是一些在开发过程中可能需要用到的关键技术&#xff1a; 前端开发技术&#xff1a;前端部分主要负责用户界面的设计和实现。通常使用HTML、CSS和JavaScript等技…

YARN-Client 与 YARN-Cluster 区别

YARN-Client 与 YARN-Cluster 区别 理解YARN-Client和YARN-Cluster深层次的区别之前先清楚一个概念&#xff1a;Application Master。在YARN中&#xff0c;每个Application实例都有一个ApplicationMaster进程&#xff0c;它是Application启动的第一个容器。它负责和ResourceMa…

【HTML】制作一个简单的实时字体时钟

目录 前言 HTML部分 CSS部分 JS部分 效果图 总结 前言 无需多言&#xff0c;本文将详细介绍一段HTML代码&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建一个文本文档&#xff0c;两个文件夹&#xff0c;其中HTML的文件名改为[index.html]&am…

Jmeter杂记:测试计划参数详解

测试计划各参数详解 1&#xff0c;用户自定义变量&#xff0c;是全局变量&#xff0c;供所有线程组使用&#xff0c;可用配置元件&#xff1a;用户自定义变量替代 2&#xff0c;连续的运行线程组&#xff0c;默认不勾选&#xff0c;则随机的运行多个线程组中的取样器&#xff…

在隐私计算应用中和数链具备哪些技术特点?

在加速“可信数字化”进程的背景下&#xff0c;我国区块链产业将在打造新型平台经济&#xff0c;开启共享经济新时代的同时&#xff0c;带动数字经济“脱虚向实”服务实体经济。 和数软件在加速数字化进程的同时&#xff0c;进一步服务实体经济&#xff0c;提高实体经济的活力…

VS2019 VS2022 LNK2019 无法解析的外部符号sprintf

解决方案&#xff1a; 项目属性》配置属性》链接接-》输入》附加依赖项&#xff0c;增加 legacy_stdio_definitions.lib legacy_stdio_definitions.lib 是一个库文件&#xff0c;通常与使用 Visual Studio 编译的 C/C 项目相关。它的作用是解决在使用新版本的 Visual Studio 编…

IIS中部署netcore程序出现500错误如何处理?

500错误在IIS部署中经常出现&#xff0c;但是解决非常耗时 官方也有给出一些指引&#xff0c;但是无法解决根本问题 建议检查netcore相关组件是否正确安装&#xff0c;如下&#xff1a; aspnetcore-runtime-3.1.32-win-x64 dotnet-hosting-3.1.32-win dotnet-runtime-3.1.…

两数相加(leetcode)

给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 …

Intel VAAPI/QSV/oneVPL区别简介

一、常用视频加速接口汇总 libmfx就是Intel QSV. 二、VAAPI VAAPI (视频加速API&#xff0c;Video Acceleration API)包含一套开源的库(LibVA) 以及API规范, 用于硬件加速下的视频编解码以及处理&#xff0c;只有Linux上的驱动提供支持。由Intel主导&#xff0c;但是AMD&…

51单片机上面的IIC协议

1、什么是IIC协议 2、模拟IIC协议 51单片机上面是没有与IIC协议相关的寄存器的&#xff08;没有相关的硬件&#xff09;&#xff0c;不像串口可以配置对应的寄存器达到目的&#xff08;比如修改波特率9600 or 115200&#xff09;&#xff0c;要配置IIC只能够根据用户手册里面的…

未来课堂革命:OpenAI 发布 ChatGPT 使用指南,探索生成式 AI 如何重塑教育景观

随着新学期的来临&#xff0c;众多初登教师舞台的 00 后们&#xff0c;也完成了他们的第一个教师身份下的暑期生活。 对于开学的抵触情绪&#xff0c;不仅学生们普遍存在&#xff0c;许多 00 后的新晋教师们也同样感同身受。某种程度上&#xff0c;这些抗拒上班的年轻教师群体…

Java日期正则表达式(附Demo)

目录 前言1. 基本知识2. Demo 前言 对于正则匹配&#xff0c;在项目实战中运用比较广泛 原先写过一版Python相关的&#xff1a;ip和端口号的正则表达式 1. 基本知识 对于日期的正则相对比较简单 以下是一些常见的日期格式及其对应的正则表达式示例&#xff1a; 年-月-日&a…

亚马逊的核心壁垒:物流

物流为美国电商市场渗透及格局的核心影响因素&#xff0c;也是亚马逊的核心壁垒所在。 从行业规模来看&#xff0c;美国电商渗透率低于中国&#xff0c;主要由于 两国地理及人口密度差异导致美国物流履约难度更大&#xff0c;此外美国更发达的实 体零售业和更为严苛的电商政策…

弹簧、质量的bode、nyquist与根轨迹图

在控制系统分析中&#xff0c;Bode图、Nyquist图和根轨迹图都是重要的工具&#xff0c;用于评估和分析系统的性能。这些系统的Nyquist图提供了最大的旋转&#xff0c;即它们在频率变化时表现出最大的相位变化。当Nyquist图完全位于虚轴上时&#xff0c;意味着系统的增益&#x…

代码解读:使用Stable Diffusion完成相似图像生成任务

Diffusion models代码解读&#xff1a;入门与实战 前言&#xff1a;作为内容生产重要的一部分&#xff0c;生成相似图像是一项有意义的工作&#xff0c;例如很多内容创作分享平台单纯依赖用户贡献的图片已经不够了&#xff0c;最省力的方法就是利用已有的图片生成相似的图片作为…

C中自定义类型——结构体

一.前言 在C语言中&#xff0c;不仅有int、char、short、long等内置类型&#xff0c;C语言还有一种特殊的类型——自定义类型。该类型可以由使用者自己定义&#xff0c;可以解决一些复杂的个体。 二.结构体 2.1结构体的声明 我们在利用结构体的时候一般是用于描述一些有多种…

代码随想录算法训练营第三十一天| 455.分发饼干、376.摆动序列、53.最大子序和

系列文章目录 目录 系列文章目录455.分发饼干贪心算法大饼干喂胃口大的&#xff08;先遍历胃口&#xff09;胃口大的先吃大饼干(先遍历饼干&#xff09;小饼干先喂胃口小的&#xff08;先遍历胃口&#xff09;胃口小的先吃小饼干&#xff08;先遍历饼干&#xff09; 376. 摆动序…

Claude使用教程

claude 3 opus面世后&#xff0c;网上盛传吊打了GPT-4。网上这几天也已经有了许多应用&#xff0c;但竟然还有很多小伙伴不知道国内怎么用gpt&#xff0c;也不知道怎么去用这个据说已经吊打了gpt-4的claude3。 今天我们想要进行的一项尝试就是—— 用claude3和gpt4&#xff0c…

2024-04-11最新dubbo+zookeeper下载安装,DEMO展示

dubbozookeeper下载安装 下载zookeeper&#xff1a; 下载地址 解压&#xff0c;并进入bin目录&#xff0c;启动 如果闪退可以编辑脚本&#xff0c;在指定位置加上暂停脚本 报错内容说没有conf/zoo.cfg&#xff0c;就复制zoo_sample.cfg重命名为zoo.cfg 再次启动脚本&#x…

HarmonyOS开发实例:【手势截屏】

介绍 本篇Codelab基于手势处理和截屏能力&#xff0c;介绍了手势截屏的实现过程。样例主要包括以下功能&#xff1a; 根据下滑手势调用全屏截图功能。全屏截图&#xff0c;同时右下角有弹窗提示截图成功。根据双击手势调用区域截图功能。区域截图&#xff0c;通过调整选择框大…