位运算的概念

文章目录

  • 整数在计算机中的表示
    • 二进制表示
    • 有符号类型和无符号类型
    • 机器数和真值
    • 原码、反码和补码
      • 原码、反码和补码的表示方法
      • 计算机中的表示
  • 位运算
    • 与、或、异或和取反
    • 移位运算
    • 移位运算与乘除法的关系
    • 位运算的性质
  • 目录

整数在计算机中的表示

二进制表示

程序中的所有数在计算机中的表示形式都是二进制,二进制使用两个数码: 0 0 0 1 1 1

一位二进制数称为一个比特(bit),可能取值有 2 2 2 个, k k k 位二进制数的可能取值有 2 k 2^k 2k 个。

8 8 8 个比特组成一个字节(byte),一个字节的可能取值有 2 8 = 256 2^8 = 256 28=256 个。

计算机中有多种表示整数的数据类型,每种数据类型的字节数各不相同,取值范围也各不相同。Java 的整数数据类型有以下四种。

  • 字节型,用 byte \texttt{byte} byte 表示,包含 1 1 1 个字节,即 8 8 8 位二进制数,可能取值有 2 8 2^8 28 个。

  • 短整型,用 short \texttt{short} short 表示,包含 2 2 2 个字节,即 16 16 16 位二进制数,可能取值有 2 16 2^{16} 216 个。

  • 整型,用 int \texttt{int} int 表示,包含 4 4 4 个字节,即 32 32 32 位二进制数,可能取值有 2 32 2^{32} 232 个。

  • 长整型,用 long \texttt{long} long 表示,包含 8 8 8 个字节,即 64 64 64 位二进制数,可能取值有 2 64 2^{64} 264 个。

有符号类型和无符号类型

计算机中的数据类型包括有符号类型和无符号类型,这两种类型表示的整数分别称为有符号整数和无符号整数。

有符号整数中,最高位用于表示符号,因此最高位又称符号位,最高位是 0 0 0 表示非负数,最高位是 1 1 1 表示负数。无符号整数中,不存在用于表示符号的位,因此无符号整数都是非负数。

有符号整数的表示范围包括非负整数和负整数,无符号整数的表示范围只有非负整数。在位数相同的情况下,无符号整数可以表示的最大值大于有符号整数可以表示的最大值。

C、C++、C# 等语言支持有符号类型和无符号类型,Java 只支持有符号类型。

机器数和真值

一个数在计算机中的二进制表示形式称为这个数的机器数。机器数是有符号数,最高位是符号位, 0 0 0 表示非负数, 1 1 1 表示负数。

因为机器数的最高位是符号位,所以机器数的形式值不一定等于真正数值。为了区别形式值和真正数值,将机器数对应的真正数值称为真值。

考虑 1 1 1 个字节的二进制数表示的机器数。十进制的 + 20 +20 +20 对应的机器数是 00010100 00010100 00010100,十进制的 − 20 -20 20 对应的机器数是 10010100 10010100 10010100

机器数 00010100 00010100 00010100 的形式值是 20 20 20,与真正数值相等。机器数 10010100 10010100 10010100 的形式值是 148 148 148,与真正数值不相等。

原码、反码和补码

原码、反码和补码的表示方法

原码是机器数的符号位加上机器数的真值的绝对值,最高位是符号位,其余位表示数值。

反码和补码在原码的基础上得到。

非负数的反码与原码相同,负数的反码是将原码的除了符号位之外的每一位取反。

非负数的补码与原码相同,负数的补码是将原码的除了符号位之外的每一位取反,然后加 1 1 1

考虑 1 1 1 个字节的二进制数表示。

+ 20 +20 +20 的原码、反码和补码都是 00010100 00010100 00010100

− 20 -20 20 的原码是 10010100 10010100 10010100,反码是 11101011 11101011 11101011,补码是 11101100 11101100 11101100

根据上述例子可知,同一个非负数的原码、反码和补码的表示方法相同,同一个负数的原码、反码和补码的表示方法不同。其中,原码是人脑最容易理解和计算的表示方法,相比之下,反码和补码的表示方法不直观,通常需要转换成原码才能计算其数值。

计算机中的表示

虽然有符号数的二进制表示有原码、反码和补码三种表示方法,但是计算机使用补码的表示方法。

对于计算机而言,判断符号位将导致运算变得复杂,为了简化运算,将符号位也参与运算。

对于 k k k 位二进制数表示,可能取值有 2 k 2^k 2k 个。考虑原码、反码和补码三种表示方法可以表示的数值范围。

使用原码,可以表示的数值范围是 [ − ( 2 k − 1 − 1 ) , 2 k − 1 − 1 ] [-(2^{k - 1} - 1), 2^{k - 1} - 1] [(2k11),2k11],该范围的不同数值有 2 k − 1 2^k - 1 2k1 个,数值 0 0 0 存在 + 0 +0 +0 − 0 -0 0 的两个不同的原码表示。使用原码的另一个问题是,做减法运算会导致错误的结果。虽然原码是人脑容易理解和计算的表示方法,但是由于原码存在上述两个问题,因此不适用于计算机。

使用反码,可以表示的数值范围是 [ − ( 2 k − 1 − 1 ) , 2 k − 1 − 1 ] [-(2^{k - 1} - 1), 2^{k - 1} - 1] [(2k11),2k11],该范围的不同数值有 2 k − 1 2^k - 1 2k1 个,数值 0 0 0 存在 + 0 +0 +0 − 0 -0 0 的两个不同的反码表示。虽然使用反码可以解决减法运算结果错误的问题,但是仍存在 + 0 +0 +0 − 0 -0 0 的问题,因此不适用于计算机。

使用补码,可以表示的数值范围是 [ − 2 k − 1 , 2 k − 1 − 1 ] [-2^{k - 1}, 2^{k - 1} - 1] [2k1,2k11],该范围的不同数值有 2 k 2^k 2k 个,每个数值都只有一个补码表示。补码可以同时解决减法运算结果错误的问题和存在 + 0 +0 +0 − 0 -0 0 的问题,而且比原码和反码多表示一个最小值,因此计算机使用补码的表示方法。

位运算

在计算机的底层,一切运算都是基于位运算实现的。

位运算共有 6 6 6 种,分别是:与、或、异或、取反、左移和右移,其中左移和右移运算统称移位运算,移位运算又分为算术移位和逻辑移位。

上述位运算中,只有取反是一元运算,其余的都是二元运算。

与、或、异或和取反

与运算的符号是 & \& &,运算规则是:对于每个二进制位,当两个数对应的位都是 1 1 1 时,结果是 1 1 1,否则结果是 0 0 0

0 & 0 = 0 0 & 1 = 0 1 & 0 = 0 1 & 1 = 1 \begin{aligned} 0~\&~0 &= 0 \\ 0~\&~1 &= 0 \\ 1~\&~0 &= 0 \\ 1~\&~1 &= 1 \end{aligned} 0 & 00 & 11 & 01 & 1=0=0=0=1

或运算的符号是 ∣ | ,运算规则是:对于每个二进制位,当两个数对应的位中至少有一个是 1 1 1 时,结果是 1 1 1,否则结果是 0 0 0

0 ∣ 0 = 0 0 ∣ 1 = 1 1 ∣ 0 = 1 1 ∣ 1 = 1 \begin{aligned} 0~|~0 &= 0 \\ 0~|~1 &= 1 \\ 1~|~0 &= 1 \\ 1~|~1 &= 1 \end{aligned} 0  00  11  01  1=0=1=1=1

异或运算的符号是 ⊕ \oplus (代码中的异或运算符是 ∧ \wedge ),运算规则是:对于每个二进制位,当两个数对应的位中有且只有一个是 1 1 1 时,结果是 1 1 1,否则结果是 0 0 0

0 ⊕ 0 = 0 0 ⊕ 1 = 1 1 ⊕ 0 = 1 1 ⊕ 1 = 0 \begin{aligned} 0 \oplus 0 &= 0 \\ 0 \oplus 1 &= 1 \\ 1 \oplus 0 &= 1 \\ 1 \oplus 1 &= 0 \end{aligned} 00011011=0=1=1=0

取反运算的符号是 ∼ \sim ,运算规则是:对一个数的每个二进制位进行取反操作, 0 0 0 变成 1 1 1 1 1 1 变成 0 0 0

∼ 0 = 1 ∼ 1 = 0 \begin{aligned} \sim 0 &= 1 \\ \sim 1 &= 0 \end{aligned} 01=1=0

移位运算

移位运算按照移位方向分类可以分成左移和右移,按照是否带符号分类可以分成算术移位和逻辑移位。

左移运算时,将全部二进制位向左移动若干位,高位丢弃,低位补 0 0 0。对于左移运算,算术移位和逻辑移位是相同的。左移运算的符号是 < < << <<

右移运算时,将全部二进制位向右移动若干位,低位丢弃,高位的补位由算术移位或逻辑移位决定。

  • 算术右移时,高位补最高位。

  • 逻辑右移时,高位补 0 0 0

Java 中,算术右移运算的符号是 > > >> >>,逻辑右移运算的符号是 > > > >>> >>>

C、C++、C# 等语言中,右移运算的符号是 > > >> >>,不区分算术右移和逻辑右移,而是根据数据类型中的有符号类型和无符号类型区分算术右移和逻辑右移。对于有符号类型,右移运算为算术右移;对于无符号类型,右移运算为逻辑右移。

移位运算与乘除法的关系

移位运算与乘除法有密切的关联性,使用位运算实现乘除法的效率高于直接计算乘除法的效率。

左移运算对应乘法运算。将一个数左移 k k k 位,等价于将这个数乘以 2 k 2^k 2k。如果左移运算之后的结果超出特定类型的整数的表示范围,则运算结果溢出,最高位被舍弃。

算术右移对应除法运算。将一个数右移 k k k 位,相当于将这个数除以 2 k 2^k 2k,结果向下取整。

将一个数左移 k k k 位和使用乘号计算这个数乘以 2 k 2^k 2k 的结果一定相同,但是将一个数右移 k k k 位和使用除号计算这个数除以 2 k 2^k 2k 的结果不一定相同。由于使用除号计算整数除法的结果向零取整,而使用算术右移计算整数除法的结果向下取整,因此当被除数是非负数时两者的结果相同,当被除数是负数时两者的结果可能不同。

位运算的性质

位运算的性质有很多,此处列举位运算中的与、或、异或和取反的常见性质。假设以下出现的变量都是有符号整数。

  • 与运算性质: 0 & x = 0 0 ~\&~ x = 0 0 & x=0 x & 0 = 0 x ~\&~ 0 = 0 x & 0=0 x & ( − 1 ) = x x ~\&~ (-1) = x x & (1)=x x & ( ∼ x ) = 0 x ~\&~ (\sim x) = 0 x & (x)=0

  • 或运算性质: 0 ∣ x = x 0 ~|~ x = x 0  x=x x ∣ 0 = x x ~|~ 0 = x x  0=x x ∣ ( ∼ x ) = − 1 x ~|~ (\sim x) = -1 x  (x)=1

  • 异或运算性质: 0 ⊕ x = x 0 \oplus x = x 0x=x x ⊕ 0 = x x \oplus 0 = x x0=x x ⊕ x = 0 x \oplus x = 0 xx=0

  • 取反运算性质: − 1 = ∼ 0 -1 = \sim 0 1=∼0 − x = ∼ ( x − 1 ) -x = \sim (x - 1) x=∼(x1)

  • 幂等律(注意异或运算不适用): x & x = x x ~\&~ x = x x & x=x x ∣ x = x x ~|~ x = x x  x=x

  • 交换律: x & y = y & x x ~\&~ y = y ~\&~ x x & y=y & x x ∣ y = y ∣ x x ~|~ y = y ~|~ x x  y=y  x x ⊕ y = y ⊕ x x \oplus y = y \oplus x xy=yx

  • 结合律: ( x & y ) & z = x & ( y & z ) (x ~\&~ y) ~\&~ z = x ~\&~ (y ~\&~ z) (x & y) & z=x & (y & z) ( x ∣ y ) ∣ z = x ∣ ( y ∣ z ) (x ~|~ y) ~|~ z = x ~|~ (y ~|~ z) (x  y)  z=x  (y  z) ( x ⊕ y ) ⊕ z = x ⊕ ( y ⊕ z ) (x \oplus y) \oplus z = x \oplus (y \oplus z) (xy)z=x(yz)

  • 分配律: ( x & y ) ∣ z = ( x ∣ z ) & ( y ∣ z ) (x ~\&~ y) ~|~ z = (x ~|~ z) ~\&~ (y ~|~ z) (x & y)  z=(x  z) & (y  z) ( x ∣ y ) & z = ( x & z ) ∣ ( y & z ) (x ~|~ y) ~\&~ z = (x ~\&~ z) ~|~ (y ~\&~ z) (x  y) & z=(x & z)  (y & z) ( x ⊕ y ) & z = ( x & z ) ⊕ ( y & z ) (x \oplus y) ~\&~ z = (x ~\&~ z) \oplus (y ~\&~ z) (xy) & z=(x & z)(y & z)

  • 德·摩根律: ∼ ( x & y ) = ( ∼ x ) ∣ ( ∼ y ) \sim(x ~\&~ y) = (\sim x) ~|~ (\sim y) (x & y)=(x)  (y) ∼ ( x ∣ y ) = ( ∼ x ) & ( ∼ y ) \sim(x ~|~ y) = (\sim x) ~\&~ (\sim y) (x  y)=(x) & (y)

  • 其他性质:

    • x & ( x − 1 ) x ~\&~ (x - 1) x & (x1) 的结果为将 x x x 的二进制表示的最后一个 1 1 1 变成 0 0 0

    • x & ( − x ) x ~\&~ (-x) x & (x)(与 x & ( ∼ ( x − 1 ) ) x ~\&~ (\sim (x - 1)) x & ((x1)) 等价)的结果为只保留 x x x 的二进制表示的最后一个 1 1 1,其余的 1 1 1 都变成 0 0 0

上述性质在位运算的题目中经常使用到。

目录

  1. 位运算题目:数组异或操作
  2. 位运算题目:解码异或后的数组
  3. 位运算题目:交替位二进制数
  4. 位运算题目:位 1 的个数
  5. 位运算题目:比特位计数
  6. 位运算题目:汉明距离
  7. 位运算题目:颠倒二进制位
  8. 位运算题目:二进制手表
  9. 位运算题目:二进制间距
  10. 位运算题目:数字的补数
  11. 位运算题目:数字转换为十六进制数
  12. 位运算题目:两整数之和
  13. 位运算题目:或运算的最小翻转次数
  14. 位运算题目:最大单词长度乘积
  15. 位运算题目:UTF-8 编码验证
  16. 位运算题目:汉明距离总和
  17. 位运算题目:数字范围按位与
  18. 位运算题目:N 天后的牢房
  19. 位运算题目:形成两个异或相等数组的三元组数目
  20. 位运算题目:连接连续二进制数字
  21. 位运算题目:格雷编码
  22. 位运算题目:循环码排列
  23. 位运算题目:解码异或后的排列
  24. 位运算题目:两数相除
  25. 位运算题目:寻找重复数
  26. 位运算题目:按位与为零的三元组
  27. 位运算题目:安排电影院座位
  28. 位运算题目:黑板异或游戏
  29. 位运算题目:找到最接近目标值的函数值
  30. 位运算题目:找出最长的超赞子字符串

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

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

相关文章

1/30每日一题

从输入 URL 到页面展示到底发生了什么&#xff1f; 1. 输入 URL 与浏览器解析 当你在浏览器地址栏输入 URL 并按下回车&#xff0c;浏览器首先会解析这个 URL&#xff08;统一资源定位符&#xff09;&#xff0c;比如 https://www.example.com。浏览器会解析这个 URL 中的不同…

基于深度学习的视觉检测小项目(十七) 用户管理后台的编程

完成了用户管理功能的阶段。下一阶段进入AI功能相关。所有的资源见文章链接。 补充完后台代码的用户管理界面代码&#xff1a; import sqlite3from PySide6.QtCore import Slot from PySide6.QtWidgets import QDialog, QMessageBoxfrom . import user_manage # 导入使用ui…

每日 Java 面试题分享【第 20 天】

欢迎来到每日 Java 面试题分享栏目&#xff01; 订阅专栏&#xff0c;不错过每一天的练习 今日分享 3 道面试题目&#xff01; 评论区复述一遍印象更深刻噢~ 目录 问题一&#xff1a;什么是 BIO、NIO、AIO&#xff1f;问题二&#xff1a;什么是 Channel&#xff1f;问题三&…

如何解决云台重力补偿?

如何解决云台重力补偿? 最近在调试步兵云台的时候,由于枪管、图传、摄像头等重力的原因,pitch轴的参数尤其难以调整,又不想抬升和降低使用两套不同的参数,所以使用了重力补偿,效果也是比较理想的,于是整理为一篇文章记录一下 一、问题根源:枪管重力在“搞事情” 想象…

Vue指令v-html

目录 一、Vue中的v-html指令是什么&#xff1f;二、v-html指令与v-text指令的区别&#xff1f; 一、Vue中的v-html指令是什么&#xff1f; v-html指令的作用是&#xff1a;设置元素的innerHTML&#xff0c;内容中有html结构会被解析为标签。 二、v-html指令与v-text指令的区别…

软考高项笔记 信息技术及其发展

信息技术及其发展 ❝ 信息系统项目管理师第二章第一节 1. 网络标准协议的定义 网络协议是为计算机网络中进行数据交换而建立的规则、标准或约定的集合。网络协议由三个要素组成&#xff0c;分别是语义、语法和时序。 语义&#xff1a;解释控制信息每个部分的含义&#xff0c;它…

【C++ STL】vector容器详解:从入门到精通

【C STL】vector容器详解&#xff1a;从入门到精通 摘要&#xff1a;本文深入讲解C STL中vector容器的使用方法&#xff0c;涵盖常用函数、代码示例及注意事项&#xff0c;助你快速掌握动态数组的核心操作&#xff01; 一、vector概述 vector是C标准模板库&#xff08;STL&am…

深入解析 Chrome 浏览器的多进程架构:标签页是进程还是线程?(中英双语)

深入解析 Chrome 浏览器的多进程架构&#xff1a;标签页是进程还是线程&#xff1f; 1. 引言 Google Chrome 作为全球最流行的浏览器之一&#xff0c;以其稳定性、安全性和多任务处理能力而闻名。而其高效的表现&#xff0c;很大程度上归功于其独特的多进程架构&#xff08;M…

模型蒸馏(ChatGPT文档)

文章来源&#xff1a; https://chatgpt.cadn.net.cn/docs/guides_distillation 模型蒸馏 使用蒸馏技术改进较小的模型。 模型蒸馏允许您利用大型模型的输出来微调较小的模型&#xff0c;使其能够在特定任务上实现类似的性能。此过程可以显著降低成本和延迟&#xff0c;因为较小…

树莓派pico入坑笔记,触摸引脚

这里主要是扒一扒官方是如何实现触摸引脚的功能的&#xff0c;rp2040本身是不支持触摸传感的&#xff0c;那么官方是怎么实现的呢&#xff0c;这件事一直困扰着我&#xff0c;在官方给出的使用中&#xff0c;要求外接一颗至少为1M欧姆的电阻下拉&#xff0c;然后就可以使用触摸…

deepseek本地部署+结合思路

deepseek本地部署 配置&#xff1a; 建议配置 运行内存16GB 显卡&#xff1a;4060 操作系统&#xff1a;win11/win10 存储&#xff1a;512GB 一、安装Python 3.11环境&#xff08;参见&#xff09; 超详细的Python安装和环境搭建教程_python安装教程-CSDN博客 二、安装…

加载数据,并切分

# Step 3 . WebBaseLoader 配置为专门从 Lilian Weng 的博客文章中抓取和加载内容。它仅针对网页的相关部分&#xff08;例如帖子内容、标题和标头&#xff09;进行处理。 加载信息 from langchain_community.document_loaders import WebBaseLoader loader WebBaseLoader(w…

AI(计算机视觉)自学路线

本文仅用来记录一下自学路线方便日后复习&#xff0c;如果对你自学有帮助的话也很开心o(*&#xffe3;▽&#xffe3;*)ブ B站吴恩达机器学习->B站小土堆pytorch基础学习->opencv相关知识&#xff08;Halcon或者opencv库&#xff09;->四类神经网络&#xff08;这里跟…

计算机组成原理——存储系统(二)

&#x1f331; "人生最深的裂痕&#xff0c;往往是光照进来的地方。 别怕脚下的荆棘&#xff0c;那是你与平庸划清界限的勋章&#xff1b;别惧眼前的迷雾&#xff0c;星辰永远藏在云层之上。真正的强者不是从未跌倒&#xff0c;而是把每一次踉跄都踏成攀登的阶梯。记住&am…

解锁豆瓣高清海报(二) 使用 OpenCV 拼接和压缩

解锁豆瓣高清海报(二): 使用 OpenCV 拼接和压缩 脚本地址: 项目地址: Gazer PixelWeaver.py pixel_squeezer_cv2.py 前瞻 继上一篇“解锁豆瓣高清海报(一) 深度爬虫与requests进阶之路”成功爬取豆瓣电影海报之后&#xff0c;本文将介绍如何使用 OpenCV 对这些海报进行智…

OSCP - Proving Grounds - Roquefort

主要知识点 githook 注入Linux path覆盖 具体步骤 依旧是nmap扫描开始&#xff0c;3000端口不是很熟悉&#xff0c;先看一下 Nmap scan report for 192.168.54.67 Host is up (0.00083s latency). Not shown: 65530 filtered tcp ports (no-response) PORT STATE SERV…

记忆化搜索和动态规划 --最长回文子串为例

记忆化搜索 记忆化搜索是一种优化递归算法的方法&#xff0c;通过将已经计算过的子问题的结果存储起来&#xff08;通常使用哈希表或数组&#xff09;&#xff0c;避免重复计算相同的子问题。 本质上是通过缓存中间结果来减少计算的重复性。 动态规划 动态规划是通过将问题分…

最新功能发布!AllData数据中台核心菜单汇总

🔥🔥 AllData大数据产品是可定义数据中台,以数据平台为底座,以数据中台为桥梁,以机器学习平台为中层框架,以大模型应用为上游产品,提供全链路数字化解决方案。 ✨奥零数据科技官网:http://www.aolingdata.com ✨AllData开源项目:https://github.com/alldatacenter/…

Windows图形界面(GUI)-QT-C/C++ - QT Stacked Widget

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 一、概述 二、使用场景 1. 多步表单 2. 选项卡界面 3. 状态机界面 三、常见样式 四、属性设置 1. 页面管理 2. 布局管理 3. 信号与槽 五、内容处理 1. 添加页面 2. 移除页面 3.…

TensorFlow 简单的二分类神经网络的训练和应用流程

展示了一个简单的二分类神经网络的训练和应用流程。主要步骤包括&#xff1a; 1. 数据准备与预处理 2. 构建模型 3. 编译模型 4. 训练模型 5. 评估模型 6. 模型应用与部署 加载和应用已训练的模型 1. 数据准备与预处理 在本例中&#xff0c;数据准备是通过两个 Numpy 数…