位运算算法篇:进入位运算的世界

位运算算法篇:进入位运算的世界

本篇文章是我们位运算算法篇的第一章,那么在我们是算法世界中,有那么多重要以及有趣的算法,比如深度优先搜索算法以及BFS以及动态规划算法等等,那么我们位运算在这些算法面前相比,位运算就显得十分的低调,但是它仍然是一个十分重要的算法,所以我将用三到四篇文章来介绍我们的位运算,帮你领略我们位运算的神奇与各种骚操作,那么废话不多说,我们进入我们位运算的学习

1.二进制

那么在了解我们各种位运算之前,我们得先知道我们为什么要学习我们的位运算,对于我们的计算机来说,我们计算机的底层硬件只能识别由0和1组成的二进制语言,那么意味着任何数据在底层都是以二进制的形式存储的,其中就包括我们的各种数据类型比如我们的整形以及字符类型等等,那么既然这些数据统一都是以二进制形式存取,那么我们的位运算就是以二进制序列为基础展开的运算,所以可想而知位运算的重要性。


那么我们刚才也说了,各种的整形底层也都是以二进制的形式存在,那么对于我们的整形来说,我们可以将一个整形分为无符号整形以及有符号整形,那么所谓无符号整形我们很好理解,那么该整形的二进制位全部都用来作为数值位,那么也就意味着我们的无符号整形只有非负数,那么以32位的int类型为例,那么它的32个二进制位都可以作数值位,那么每一个二进制位要么是0要么是1,那么也就意味着我们的int类型的范围是0到2的32次方减一。

而对于有符号整形,我们知道在我们现实生活中,我们用正负号来区分我们的数的正负,而在我们计算机世界中,我们的数据只有0和1组成,任何数据都只能表示为0与1组成的二进制序列,那么要表达正负数,我们将一个数的最高位设置为符号位,其中0表示为正数,那么1表示为负数,其余则是作为数值位

那么对于正数来说,除了最最高位为0,其余都是数值位,那么我们按照每个数值位所对应的权值来得到一个十进制数,但是对于负数,我们采取了一个特殊的设计

那么我们的整形分为了原码以及反码和补码,那么我们计算机中存取的都是补码,那么我们正数的原码以及反码和补码都是一样的,而对于我们的负数来说,我们得到一个负数的补码,那么首先我们得将负数的补码除最改为符号位其余按位取反,然后再加1就得到我们的负数的原码,那么我们该原码的数值位就是我们该负数的绝对值,那么我们得到负数的绝对值,前面加一个符号即可。所以我们看到一个整形的二进制序列,先看符号位,如果是0,代表正数,1则是负数,然后将其转换为原码来解读出它对应的10进制数

假设以4个比特位为例: 1110

1.最高位是1,那么负数

2.按位取反(~) 1001

3.取反后再加1 1010

4.解读数值位 得到 -2

那么相信通过我刚才的介绍你一定能够熟练的掌握有符号整形的识别与转化,那么想必你一定有一个疑问,那么也就是我们对于负数为什么要这么设计呢?

那么我们知道我们的CPU的计算机只有我们的加法器,那么我们关于我们整形的乘法以及出发运算都要通过我们的加法运算来实现,那么对于加法运算来说,我们的正数加正数那么就正常的按照我们二进制的计算规则逢2进1计算即可,但是对于正数加负数,那么我们知道我们正数加负数,我们现实世界中计算,那么我们首先得判断两个数的绝对值,然后让绝对值大的减去绝对值小的,那么我们要做到,必然就要涉及到条件判断,那么条件判断肯定会影响效率,所以能不能采取统一的规则,不关心该数是正还是负,都能用统一的方式来计算,那么这就是补码出现的意义:

那么它做到了让我们计算一个二进制序列不要关心正负,按照正数加正数的那套逻辑得到值,如果是负数的话,我们按照上文所说的,将其转换为原码就能得到该数的具体数值是什么了,你下来可以动手实践一下,结果肯定都是一定满足的。

比如5+(-3)假设以4个比特位为例

那么5的二进制序列0101

​ 3的补码:1101

​ 计算过程 0101

​ 1101

​ -----------

​ 0010

那么0010对应的10进制数就是我们的2

2.位运算

那么刚才引入了二进制的相关知识,那么我们再来介绍我们几个常见的位运算,

那么我们的位运算可以分为两大类,分别是算术运算以及逻辑运算,那么我们首先先讲解一下我们的算术运算:

或运算(|):

那么我们的或运算的运算规则则是对应的二进制位只要为1,那么结果一定为1,如果对应的二进制位全部是0,那么计算的结果才是0,或运算同时可以引入到逻辑运算中,只有运算的条件全部为false,结果才为false

0 | 0 =0

1| 0=1

1 | 1=1

与运算(&):

与运算的规则则是我们对应的二进制位全部为1结果才为1,其余则全是0,对应逻辑运算则是条件全为真,结果才为真。

1 & 1=1

1& 0 =0

异或运算(^):

异或运算的规则则是相同为0,相异为1

1^0 =1

1^ 1=0

0^ 0=0

右移运算符:

那么我们的右移运算符则分为两种分别是算术右移以及逻辑右移

那么逻辑右移(>>>)则是我们将我们的二进制序列整体往右移动,然后左边补0,但是我们知道对于有符号整形来说,它的最高位为符号位,那么如果采取这种右移方式,那么它的正负会颠倒,对数值会改变,所以我们有第二种方式

算术右移(>>),那么它则是左边不是补0,而是补充符号位,那么对于负数来说,那么它则是会在左边依次补1。

并且我们要注意我们的右移运算符,那么它只是一个动作,也就是说我们对一个整形的变量左移了n位,那么右移后的结果会保存在一个临时变量中,而不是对原变量直接进行右移,同理对于左移,那么我们可以简单的用代码来验证:

#include <stdio.h>int main() {int original = 8; // 二进制:00001000int leftShifted = original << 2; // 左移两位,二进制:00010000,即16int rightShifted = original >> 2; // 右移两位,二进制:00000010,即2printf("Original: %d\n", original);printf("Left Shifted: %d\n", leftShifted);printf("Right Shifted: %d\n", rightShifted);return 0;
}

在这里插入图片描述

左移运算符(<<):

那么我们的左移运算符就不用像刚才的那样分为逻辑以及算术,那么我们的左移运算符的右边统一用0来补充。

那么对于逻辑右移运算符以及左移运算,我们每次逻辑左移动一位就相当于在原数的基础上除了2,每次右移动一位就相当于在原数的基础上乘以了2


逻辑运算:

逻辑或运算符(||):

那么我们的逻辑或运算符的运算规则和或运算符一致,只有有一个条件为真,结果为真,但是注意的是,我们逻辑或运算符没有穿透性,也就是说我们逻辑或运算符是从左往右依次进行条件判断,一旦判断到有一个条件表达式为真,那么它就不在执行之后的条件判断,直接返回结果为真,而我们的或运算则是要依次从左到右判断完

那么我们可以写一个代码来验证:

#include<iostream>
using namespace std;
bool returntrue(void)
{cout<<"run this succcessfully ";return true;
}
bool returnfalse(void)
{cout<<"run this successfully";return false;
}
int main()
{cout<<"Test1:"<<endl;bool res=returntrue()||returnfalse();cout<<endl;cout<<"Test2:"<<endl;res=returntrue()|returnfalse();return 0;
}

在这里插入图片描述

逻辑与运算符(&&):

运算规则也是和与&运算一致,但是注意我们的逻辑与运算也不具有穿透性,它也是从左往右依次判断条件表达式的真值,一旦我们的中间的某个条件表达式为假,那么它就不再往后执行后面的条件判断语句,直接返回false

同样也是与上面一套的代码逻辑稍加修改来验证:

#include<iostream>
using namespace std;
bool returntrue(void)
{cout<<"run this succcessfully ";return true;
}
bool returnfalse(void)
{cout<<"run this successfully";return false;
}
int main()
{cout<<"Test1:"<<endl;bool res=returnfalse()&&returntrue();cout<<endl;cout<<"Test2:"<<endl;res=returntrue()|returnfalse();return 0;
}

在这里插入图片描述

3.实践

那么我们有了上述的知识,那么我们可以根据我们本篇文章所讲的全部内容来自己实现一个打印一个数的二进制序列。

那么具体实现的原理也很简单,那么就是我们的利用我们的位运算,我们对于一个int类型的数,那么它有32个二进制位,那么我们打印它所有的32个二进制位,我们就得从左往右依次打印每一个二进制位,那么我们利用我们的与运算,那么与运算的规则是对应的二进制位只要有1,那么结果为1,全部为0,结果则为0,那么我们知道我们十进制的1,那么对应的二进制序列就是只有最低位的二级制位为1,其余为0,那么我们将他依次左移到最高位,然后进行与运算,然后判断是否为0然后依次打印判断后的结果即可,那么如下则是我们的代码实现:

#include<iostream>
using namespace std;
void Print(int a)
{for(int i=31;i>=0;i--){int ant=(1<<i)&a;if(ant==0){cout<<0;}else{cout<<1;} 	}cout<<endl;
}
int main()
{int a=80;Print(a);return 0;
}

在这里插入图片描述

**注意我们如果要打印一个long类型的数,那么我们首先得将我们的1移到最高位也就是第63位,但是我们编译器默认我们的1是int类型,所以直接移动会溢出,所以我们得将我们的1设置为long类型,在进行左移

4.结语

那么本文介绍了我们的位运算的前置知识,比如整形的原反补码,和相应的位运算,那么我们在根据今天所讲的内容自己实现了一个打印一个数的二进制序列,那么下一篇文章我会详解我们的异或运算的一些骚操作,那么我们会持续更新,希望你能够多多关照与支持,希望本篇文章能够让你有所收获!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis高级数据结构HyperLogLog

文章目录 背景常见API注意事项实现原理1、哈希函数2、前导零统计3、存储与计数4、基数估算 pf 的内存占用为什么是 12k&#xff1f;总结 背景 在开始这一节之前&#xff0c;我们先思考一个常见的业务问题&#xff1a;如果你负责开发维护一个大型的网站&#xff0c;有一天老板找…

<tauri><rust><GUI>基于rust和tauri,在已有的前端框架上手动集成tauri示例

前言 本文是基于rust和tauri&#xff0c;由于tauri是前、后端结合的GUI框架&#xff0c;既可以直接生成包含前端代码的文件&#xff0c;也可以在已有的前端项目上集成tauri框架&#xff0c;将前端页面化为桌面GUI。 环境配置 系统&#xff1a;windows 10 平台&#xff1a;visu…

mysql 学习11 事务,事务简介,事务操作,事务四大特性,并发事务问题,事务隔离级别

一 事务简介&#xff0c; 数据库准备&#xff1a; create table account(id int auto_increment primary key comment 主键ID,name varchar(128) not null comment 姓名,backaccountnumber char(18) unique comment 银行账号,money float comment 余额 )comment 银行账号表;…

重塑生产制造企业项目管理新范式:项目模板在Tita中的卓越实践

在竞争激烈的生产制造领域&#xff0c;每一个项目的成功执行都是企业稳健前行的重要基石。然而&#xff0c;面对复杂多变的生产流程、严格的交货期限以及不断变化的客户需求&#xff0c;如何确保项目高效、有序地进行&#xff0c;成为了众多企业面临的共同挑战。此时&#xff0…

Ajax-介绍

概念: Asynchronous JavaScript And XML&#xff0c;异步的JavaScript和XML. 作用: 数据交换:通过Aiax可以给服务器发送请求&#xff0c;并获取服务器响应的数据 异步交互: 可以在不重新加载整个页面的情况下&#xff0c;与服务器交换数据并更新部分网页的技术, 如:搜索联想、…

基于可信数据空间的企业数据要素与流通体系建设(附ppt 下载)

近期&#xff0c;可信数据空间会议召开。大数据系统软件国家工程研究中心总工程师王晨发表了题为《基于可信数据空间的企业数据要素与流通体系建设》主旨演讲。 WeChat Subscription Account【智慧城市指北】&#xff0c;可搜索相关关键字“20250107”&#xff0c;可获取具体获…

idea整合deepseek实现AI辅助编程

1.File->Settings 2.安装插件codegpt 3.注册deepseek开发者账号&#xff0c;DeepSeek开放平台 4.按下图指示创建API KEY 5.回到idea配置api信息&#xff0c;File->Settings->Tools->CodeGPT->Providers->Custom OpenAI API key填写deepseek的api key Chat…

Composo:企业级AI应用的质量守门员

在当今快速发展的科技世界中,人工智能(AI)的应用已渗透到各行各业。然而,随着AI技术的普及,如何确保其可靠性和一致性成为了企业面临的一大挑战。Composo作为一家致力于为企业提供精准AI评估服务的初创公司,通过无代码和API双模式,帮助企业监测大型语言模型(LLM)驱动的…

增加工作台菜单页面,AI问答应用支持上下文设置,数据库表索引优化,zyplayer-doc 2.4.8 发布啦!

zyplayer-doc是一款适合企业和个人使用的WIKI知识库管理工具&#xff0c;支持在线编辑富文本、Markdown、表格、Office文档、API接口、思维导图、Drawio以及任意的文本文件&#xff0c;专为私有化部署而设计&#xff0c;最大程度上保证企业或个人的数据安全&#xff0c;支持以内…

C++开发(软件开发)常见面试题

目录 1、C里指针和数组的区别 2、C中空指针请使用nullptr不要使用NULL 3、http/https区别和头部结构&#xff1f; 4、有了mac地址为什么还要ip地址&#xff1f;ip地址的作用 5、有了路由器为什么还要交换机&#xff1f; 6、面向对象三大特性 7、友元函数 8、大端小端 …

智能理解 PPT 内容,快速生成讲解视频

当我们想根据一版 PPT 制作出相对应的解锁视频时&#xff0c;从撰写解锁词&#xff0c;录制音频到剪辑视频&#xff0c;每一个环节都需要投入大量的时间和精力&#xff0c;本方案将依托于阿里云函数计算 FC 和百炼模型服务&#xff0c;实现从 PPT 到视频的全自动转换&#xff0…

第八届大数据与应用统计国际学术研讨会(ISBDAS 2025)

重要信息 官网&#xff1a;www.is-bdas.org 时间&#xff1a;2025年2月28-3月2日 地点&#xff1a;中国 广州 主办单位&#xff1a;广东省高等教育学会人工智能与高等教育研究分会 协办单位&#xff1a;北京师范大学人工智能与未来网络研究院、人工智能与大数据科研基地 …

认识O(NlogN)的排序

归并排序 归并排序&#xff08;任何一个递归&#xff09;如果不懂可以画一个树状结构去帮助自己去理解。 核心排序方法为Merger public class 归并排序 {public static void main(String[] args) {int[] arr1 {3, 1, 2, 2, 5, 6};int[] arr2 Arrays.copyOf(arr1, arr1.len…

方波的基波和谐波详细推导,以及matlab验证[电路原理---2]

最近要滤波&#xff0c;从1KHZ 方波中获得正弦波&#xff0c;这让我们要对方波的频谱有具体的了解。虽然楼主一年前刚学过傅里叶。但也是忘的干干净净查阅资料后终于是整理出来。用漂亮的latex打出来了&#xff0c;为自己留存一份记录&#xff0c;也分享给大家学习。 方波的基…

计算机组成原理(3)

计算机组成原理&#xff08;3&#xff09; 存储器层次结构存储器概述存储器分类存储器性能指标 半导体随机存储SRAM和DRAM 存储器层次结构 主存-辅存&#xff1a;实现了虚拟存储系统&#xff0c;解决了主存容量不足的问题&#xff1b; Cache-主存&#xff1a;解决了主存于CPU速…

2024最新版Java面试题及答案,【来自于各大厂】

发现网上很多Java面试题都没有答案&#xff0c;所以花了很长时间搜集整理出来了这套Java面试题大全~ 篇幅限制就只能给大家展示小册部分内容了&#xff0c;需要完整版的及Java面试宝典小伙伴点赞转发&#xff0c;关注我后在【翻到最下方&#xff0c;文尾点击名片】即可免费获取…

DeepSeek-V3 论文解读:大语言模型领域的创新先锋与性能强者

论文链接&#xff1a;DeepSeek-V3 Technical Report 目录 一、引言二、模型架构&#xff1a;创新驱动性能提升&#xff08;一&#xff09;基本架构&#xff08;Basic Architecture&#xff09;&#xff08;二&#xff09;多令牌预测&#xff08;Multi-Token Prediction&#xf…

Mac 基于Ollama 本地部署DeepSeek离线模型

最近节日期间最火的除了《哪吒》就是deepseek了&#xff0c;毕竟又让西方各个层面都瑟瑟发抖的产品。DeepSeek凭借其强大的AI能力真的是在全球多个领域展现出强大的影响力。由于受到外部势力的恶意攻击倒是deepseek官方服务不稳定&#xff0c;国内其他厂家的适配版本也不是很稳…

51单片机之引脚图(详解)

8051单片机引脚分类与功能笔记 1. 电源引脚 VCC&#xff08;第40脚&#xff09;&#xff1a;接入5V电源&#xff0c;为单片机提供工作电压。GND&#xff08;第20脚&#xff09;&#xff1a;接地端&#xff0c;确保电路的电位参考点。 2.时钟引脚 XTAL1&#xff08;第19脚&a…

力扣刷题 题11,12

题目11 思路&#xff1a;设置左右指针 left和 right 指针指向数组的开始和末尾&#xff0c;max_water 用于记录最大容量初始为0。利用while循环left<right&#xff0c;移动指针比较数组元素 height[left] 和 height[right] 的大小&#xff0c;移动较短的那条线的指针&#x…