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

【计算机科学】位运算:揭开二进制世界的奥秘

位运算是计算机运算的一种基础操作,直接作用于数据的二进制位(bit),在计算机中具有极高的效率。无论是编写高效算法,还是进行底层开发,位运算都扮演着重要角色。本文将从位运算的起源、常见操作符、应用场景到一些实际开发中的使用技巧,带你系统性地了解位运算,并通过代码示例让你轻松掌握。


目录

  1. 位运算的来源与基本概念
  2. 常见位运算符与含义
  3. 位运算的应用实例
  4. 实际开发中的位运算技巧
  5. 总结

1. 位运算的来源与基本概念

位运算在计算机科学中是非常基础的操作,它直接作用于二进制数据的每个位。为了理解位运算,我们需要了解计算机如何存储和处理数据,以及它在底层是如何利用二进制实现高效操作的。

位运算的起源

计算机中,数据以二进制形式表示,即每一位(bit)可以是01,这正好对应电路中的“关”和“开”两种状态。这种数字逻辑电路控制构成了计算机的基础,使得位运算成为最基础的运算形式之一。

位运算起源于逻辑电路的概念,在物理层面上,逻辑门(如“与”“或”“非”门)就是通过处理电压高低来代表01。二进制位通过一系列运算符的组合,能够实现复杂的数据计算和处理。例如,加法、乘法等操作都可以通过二进制的位运算来实现。在底层,所有高级语言中的数值运算最终都会转换成硬件指令,这些指令直接在硬件层上进行位运算,从而保证高效的执行速度。

为什么使用位运算?

位运算的优点包括:

  1. 高效性
    位运算的执行速度非常快,因为计算机的CPU原生支持位操作,且操作直接在二进制位上进行。相比加减乘除,位运算可以在底层减少指令数,提升运行速度。很多高级程序中使用位运算来替代复杂计算,以提高程序效率。

  2. 节省内存
    位运算可以压缩数据,节省存储空间。例如,使用标志位可以在一个整数的二进制位表示多个布尔状态(如8个标志位),避免使用多个变量,从而减少内存消耗。这在嵌入式系统中尤其重要。

  3. 逻辑控制简单
    位运算可以直接操作二进制位,使得某些操作变得简单直观。例如,通过位运算可以轻松地设置、清除或检查某些位的状态,不必使用循环或条件语句进行复杂判断。


2. 常见位运算符与含义

运算符名称描述示例(假设 a = 5b = 3
&按位与两个二进制数的每个对应位都为1时,结果的该位为1,否则为0
应用:常用于掩码操作,例如保留数的某些特定位。
a & b = 1
``按位或两个二进制数的每个对应位只要有一个为1,结果的该位就为1
应用:用于组合多个标志位,或设置某些位为1
^按位异或两个二进制数的对应位不同则为1,相同则为0
应用:用于位翻转和交换两个变量的值,或实现简单加密。
a ^ b = 6
~按位取反将数的每个二进制位翻转,0110。这种操作等价于取负数减一。
应用:快速生成负数,或取反所有位。
~a = -6
<<左移将数的二进制位向左移动指定的位数,右侧补0,相当于乘以2^n
应用:快速计算乘法或扩大值范围。
a << 1 = 10
>>右移将数的二进制位向右移动指定的位数,左侧补符号位。等效于除以2^n
应用:快速计算除法,缩小值范围或分段数值。
a >> 1 = 2

示例与解释

  1. 按位与 &

    • 作用:常用于掩码操作,即提取数值中的特定位。例如,判断一个数是否是奇数,我们可以检查其最低位是否为1。
    • 示例if (a & 1) == 1 判断a是否为奇数,1的二进制位 0001a 的最低位相与,若为奇数,结果即为1
  2. 按位或 |

  • 作用:将多个“标志位”合并为一个数值。按位或操作会把每个位中的“1”保留下来,所以只要有一方的该位为1,结果的该位也会是1
  • 示例:假设一个用户权限系统中,用位运算代表用户的不同权限:READ权限是 0001WRITE权限是 0010。我们可以通过 READ | WRITE 来将这两个权限合并到一起,表示该用户既有读取权限,又有写入权限。
    READ = 0b0001       # 二进制:0001
    WRITE = 0b0010      # 二进制:0010
    permissions = READ | WRITE  # 结果为 0011 表示读写权限都有
    
  1. 按位异或 ^
  • 作用:当两个数的某个位不同时,按位异或会把该位设为1。否则,该位设为0。它的常用场景是交换两个变量的值,不需要使用临时变量。
  • 示例:如果我们想交换变量 ab 的值,可以使用以下代码:
    a = 5   # 二进制:0101
    b = 3   # 二进制:0011a = a ^ b   # a 变为 6(0110)
    b = a ^ b   # b 变为 5(0101,即 a 的初始值)
    a = a ^ b   # a 变为 3(0011,即 b 的初始值)
    
    经过这三步,ab 的值已经互换。这种方法常用于低级优化。

  1. 按位取反 ~
  • 作用:按位取反会将一个数的每个位都变成相反的状态,0变成11变成0
  • 示例:对于整数 5(在二进制中为 0000 0101),使用按位取反后会得到1111 1010,这个二进制数在有符号数中表示-6
    x = 5         # 二进制:0000 0101
    result = ~x   # 结果是 -6
    
    这种取反运算在位运算中可以快速生成负数的补码表示。
  1. 左移 <<

    • 作用:在位运算中,左移相当于乘2的幂。例如,将3 << 2等同于3 * 4
    • 示例3 << 1的结果是6
  2. 右移 >>

    • 作用:右移相当于将数缩小一半,适用于快速除法。
    • 示例10 >> 1 结果为5

3. 位运算的应用实例

位运算的高效性和紧凑性使其在实际开发中广泛应用于权限管理、加密解密、数据压缩、掩码操作等领域。下面是一些典型的应用场景和实例:

1. 权限管理

在权限系统中,每个权限位都可以用二进制的一个位来表示,多个权限就可以组合在一个整数中。这样做可以减少存储空间,并且方便检查、赋予或删除特定权限。

示例:权限设置和检查

假设有以下三种权限:

  • READ 权限:二进制为 001
  • WRITE 权限:二进制为 010
  • EXECUTE 权限:二进制为 100

将这三种权限组合使用位运算管理:

# 定义权限
READ = 0b001       # 读权限
WRITE = 0b010      # 写权限
EXECUTE = 0b100    # 执行权限# 组合权限
user_permissions = READ | WRITE  # 用户拥有读和写权限# 检查权限
has_read = (user_permissions & READ) != 0      # 是否有读权限
has_execute = (user_permissions & EXECUTE) != 0  # 是否有执行权限
print(f"Read: {has_read}, Execute: {has_execute}")# 添加权限
user_permissions |= EXECUTE  # 增加执行权限

通过这种方式,可以快速组合、检查或移除权限,提高权限管理的效率和代码的清晰度。

2. 加密与解密

在数据加密中,异或(XOR)操作可以用于实现简单的加密和解密。异或的特性是:a ^ b ^ b = a,即如果将某个值与密钥key进行一次异或操作可以加密,再次用同一个密钥异或可以解密回来。

示例:简单加密解密

假设我们有一个数 data 需要加密和解密:

data = 123        # 原始数据
key = 25          # 加密密钥# 加密
encrypted_data = data ^ key
print(f"Encrypted: {encrypted_data}")# 解密
decrypted_data = encrypted_data ^ key
print(f"Decrypted: {decrypted_data}")

在这个例子中,通过将 datakey 进行异或,生成了加密后的数据。再次用同样的 key 进行异或操作,就可以还原为原始数据。这种方法虽简单但不适用于高强度加密场景,适合用于简单的数据隐藏。

3. 使用掩码操作提取特定位

掩码操作可以帮助我们提取特定的二进制位,用于状态检查或分离数据。掩码通常是一个指定的二进制数,通过与原数据按位与 & 操作,可以获取特定位置上的值。

示例:提取某些位的值

假设我们有一个8位二进制数 number = 0b10101100,现在想提取其中的第3位到第5位的值。

number = 0b10101100
mask = 0b00111000  # 掩码,提取第3位到第5位result = (number & mask) >> 3  # 提取并右移3位
print(f"Extracted bits: {bin(result)}")

在这个例子中,通过 & 操作,我们将不需要的位清零,之后右移可以得到所需位的值。在嵌入式开发或低级系统编程中,掩码操作常用于读取特定的硬件状态位。

4. 数据压缩与解压

位操作也能用来压缩信息,将多个标志位或小数据段放入一个数值中。在资源受限的系统中,可以用这种方法节省内存空间。

示例:将多个布尔标志合并为一个字节

假设我们有四个标志 a, b, c, d,每个标志都占用一位,我们可以将它们压缩到一个字节中。

# 四个布尔标志
a, b, c, d = 1, 0, 1, 1# 压缩为一个字节
byte = (a << 3) | (b << 2) | (c << 1) | d
print(f"Compressed byte: {bin(byte)}")# 解压还原各标志位
a_extracted = (byte >> 3) & 1
b_extracted = (byte >> 2) & 1
c_extracted = (byte >> 1) & 1
d_extracted = byte & 1
print(f"Extracted flags: a={a_extracted}, b={b_extracted}, c={c_extracted}, d={d_extracted}")

在这个例子中,我们用位移操作将每个标志位放入一个字节中的不同位置,这样只需要一个字节就能存储多个布尔值。通过位移和按位与可以还原每个标志的值。

5. 位标记处理

在某些游戏开发和状态管理中,位标记是一种常用方式,用于表示对象的不同状态。例如,一个游戏角色的状态可能包括“跳跃中”“攻击中”“受伤中”等多个状态。我们可以用位运算来记录和管理这些状态。

示例:多状态管理

假设我们有以下状态:

  • IS_JUMPING:二进制位 0001
  • IS_ATTACKING:二进制位 0010
  • IS_HURT:二进制位 0100

通过位标记,我们可以组合多个状态,并随时检查或移除某个状态。

# 定义状态位
IS_JUMPING = 0b0001
IS_ATTACKING = 0b0010
IS_HURT = 0b0100# 初始化状态
character_state = 0# 设置状态
character_state |= IS_JUMPING  # 角色跳跃中
character_state |= IS_HURT     # 角色受伤中# 检查状态
is_jumping = (character_state & IS_JUMPING) != 0
is_attacking = (character_state & IS_ATTACKING) != 0
print(f"Jumping: {is_jumping}, Attacking: {is_attacking}")# 移除状态
character_state &= ~IS_HURT  # 角色恢复,不再受伤

在这个示例中,通过按位或来设置状态,按位与检测状态,按位与和按位取反组合则可以移除状态。位标记方式能够在单个整数中存储多个状态,提升状态管理的效率。


这些示例展示了位运算在实际开发中的一些经典应用。通过灵活使用位运算,开发者可以实现更高效的权限管理、数据加密、状态管理等功能,提高程序性能和内存利用率。


4. 实际开发中的位运算技巧

常用的位运算技巧

  1. 判断奇偶性x & 1 可以判断一个数的奇偶性。
  2. 快速乘法和除法:用左移(乘2的幂)和右移(除2的幂)进行高效计算。
  3. 交换变量:使用x = x ^ y交换两个变量。

5. 总结

位运算是编程中既基础又高效的操作工具,因其直接作用于二进制位,使其在性能优化、内存节省和数据处理上拥有显著优势。通过掌握位运算,不仅能够帮助我们在代码中实现更高效的逻辑控制和数据处理,也可以轻松处理权限、加密、状态管理等应用场景。希望本文为你提供了深入的理解和实用的技巧!

相关文章:

【计算机科学】位运算:揭开二进制世界的奥秘

位运算是计算机运算的一种基础操作&#xff0c;直接作用于数据的二进制位&#xff08;bit&#xff09;&#xff0c;在计算机中具有极高的效率。无论是编写高效算法&#xff0c;还是进行底层开发&#xff0c;位运算都扮演着重要角色。本文将从位运算的起源、常见操作符、应用场景…...

弹性裸金属服务器和传统裸金属服务器有什么区别?

弹性裸金属服务器是一种结合了传统裸金属服务器和云计算资源两种特点的服务器&#xff0c;是一种云计算服务&#xff0c;下面我们就来了解一下弹性裸金属服务器和传统裸金属服务器之间有什么区别吧&#xff01; 弹性裸金属服务器能够支持企业快速部署新的硬件和软件系统&#x…...

shodan(五)连接Mongodb数据库Jenkinsorg、net、查看waf命令

声明&#xff1a;学习素材来自b站up【泷羽Sec】&#xff0c;侵删&#xff0c;若阅读过程中有相关方面的不足&#xff0c;还请指正&#xff0c;本文只做相关技术分享,切莫从事违法等相关行为&#xff0c;本人一律不承担一切后果 引言&#xff1a; 1.Shodan 是一个专门用于搜索连…...

ThingsBoard规则链节点:Push to Edge节点详解

引言 1. Push to Edge 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 边缘计算 3.2 本地数据处理 3.3 实时响应 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台&#xff0c;提供了设备管…...

基于 EventBridge + DashVector 打造 RAG 全链路动态语义检索能力

作者&#xff1a;肯梦 本文将演示如何使用事件总线&#xff08;EventBridge&#xff09;&#xff0c;向量检索服务&#xff08;DashVector&#xff09;&#xff0c;函数计算&#xff08;FunctionCompute&#xff09;结合灵积模型服务 [ 1] 上的 Embedding API [ 2] &#xff0…...

【golang/navmesh】使用recast navigation进行寻路

目录 说在前面安装使用可视化 说在前面 go version&#xff1a;1.20.2 linux/amd64操作系统&#xff1a;wsl2detour-go版本&#xff1a;v0.2.0github&#xff1a;这里&#xff0c;求star! 安装 使用go mod安装即可go get github.com/o0olele/detour-go使用 使用场景模型构建n…...

【软考】Redis不同的数据类型和应用场景。

Redis的不同数据类型和对应的应用场景&#xff1a; Redis 数据类型及其应用场景 String&#xff08;字符串&#xff09; 特点&#xff1a;简单的值存储&#xff0c;支持二进制数据。应用场景&#xff1a; 缓存用户会话。缓存小的配置文件。缓存计数器。文章浏览量&#xff0…...

java 对人名和电话 脱敏-replaceAll

学习了《正则匹配人名》和《正则匹配电话号码》&#xff0c;如果要一起进行脱敏处理&#xff0c;改怎么做&#xff1f; 脱敏的&#xff0c;考虑配置规则&#xff0c;进行匹配的方式进行处理&#xff1a; 脱敏规则&#xff1a; DesensitizationRules Data public class Desens…...

计算机网络:网络层 —— 网络地址转换 NAT

文章目录 网络地址转换 NAT 概述最基本的 NAT 方法NAT 转换表的作用 网络地址与端口号转换 NAPTNAT 和 NAPT 的缺陷 网络地址转换 NAT 概述 尽管因特网采用了无分类编址方法来减缓 IPv4 地址空间耗尽的速度&#xff0c;但由于因特网用户数量的急剧增长&#xff0c;特别是大量小…...

【Pikachu靶场:XSS系列】xss之过滤,xss之htmlspecialchars,xss之herf输出,xss之js输出通关啦

一、xss之过滤 <svg onloadalert("过关啦")> 二、xss之htmlspecialchars javascript:alert(123) 原理&#xff1a;输入测试文本为herf的属性值和内容值&#xff0c;所以转换思路直接变为js代码OK了 三、xss之href输出 JavaScript:alert(假客套) 原理&#x…...

面向制造和装配的产品设计指南(二):面向装配的设计指南

参考引用 面向制造和装配的产品设计指南 1. 概述 1.1 装配的概念 装配是指把多个零件组装成产品&#xff0c;使得产品能够实现相应的功能并体现产品的质量&#xff0c;装配包含三层含义 把零件组装在一起实现相应的功能体现产品的质量 1.2 最好和最差的装配工序 1.3 面向装…...

Python中的PDF处理工具:PyPDF2和ReportLab使用指南

Python中的PDF处理工具&#xff1a;PyPDF2和ReportLab使用指南 在日常工作和项目中&#xff0c;PDF 文件处理是个常见需求&#xff0c;不论是合并报告、加密文档、填充表单&#xff0c;还是生成发票。Python 中有许多用于操作 PDF 文件的库&#xff0c;其中 PyPDF2 和 ReportL…...

【vxe-table】多选筛选项对列表的列进行动态的显示与隐藏

需求&#xff1a; 列表的组成部分由&#xff1a;一些固定的列&#xff0c;如:姓名&#xff0c;工号&#xff0c;以及 需要动态显示与隐藏的列&#xff0c;如&#xff1a;出勤、旷工、事假、病假等假勤类型 1、通过多选框多选&#xff0c;展示选中的列&#xff0c;未选中的不展示…...

微信小程序uniapp+vue飞机订票航空售票系统

文章目录 项目介绍具体实现截图技术介绍mvc设计模式小程序框架以及目录结构介绍错误处理和异常处理java类核心代码部分展示详细视频演示源码获取 项目介绍 对于小程序飞机订票信息管理所牵扯的信息管理及数据保存都是非常多的&#xff0c;举例像所有的管理员&#xff1b;管理员…...

如何取消Outlook中的循环会议

如何取消Outlook中的循环会议 参考链接&#xff1a;https://iknow.lenovo.com.cn/detail/195430 1、打开Outlook&#xff0c;进入 日历 视图界面&#xff1b; 2、 选择并双击要取消的循环会议&#xff1b; 3、 在 打开定期项目 对话框中选择整个序列&#xff0c;然后单击 确…...

Docker-- cgroups资源控制实战

上一篇&#xff1a;容器化和虚拟化 什么是cgroups&#xff1f; cgroups是Linux内核中的一项功能&#xff0c;最初由Google的工程师提出&#xff0c;后来被整合进Linux内核; 它允许用户将一系列系统任务及其子任务整合或分隔到按资源划分等级的不同组内&#xff0c;从而为系统…...

使用Python和Vosk库实现语音识别

使用Python和Vosk库实现语音识别 在人工智能和机器学习领域&#xff0c;语音识别技术正变得越来越重要。Python作为一种强大的编程语言&#xff0c;拥有丰富的库和框架&#xff0c;可以方便地实现语音识别功能。今天&#xff0c;我们将介绍如何使用Python中的SpeechRecognitio…...

stm32使用串口的轮询模式,实现数据的收发

------内容以b站博主keysking为原型&#xff0c;整理而来&#xff0c;用作个人学习记录。 首先在STM32CubeMX中配置 前期工作省略&#xff0c;只讲重点设置。 这里我配置的是USART2的模式。 会发现&#xff0c;PA2和PA3分别是TX与RX&#xff0c;在连接串口时需要TX对RX&…...

105. UE5 GAS RPG 搭建主菜单

在这一篇&#xff0c;我们将实现对打开游戏显示的主菜单进行搭建&#xff0c;主菜单将显示游戏主角&#xff0c;游戏名称和进入游戏和退出游戏两个按钮。 搭建菜单场景 我们将主菜单设置为一个单独的场景&#xff0c;前面可以显示对应的UI控件&#xff0c;用于玩家操作&#…...

基于 JAVASSM(Java + Spring + Spring MVC + MyBatis)框架开发一个医院挂号系统

基于 JAVASSM&#xff08;Java Spring Spring MVC MyBatis&#xff09;框架开发一个医院挂号系统是一个实用的项目。 步骤一&#xff1a;需求分析 明确系统需要实现的功能&#xff0c;比如&#xff1a; 用户注册和登录查看医生列表预约挂号查看预约记录取消预约管理员管…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...