【JavaSE】【计算机系统基础】原码、反码、补码及位运算详解(重点)

简介: 文章目录1 原码、反码与补码1.1 概述1.2 规律及方法2 位运算符2.1 位运算符概述2.2 计算 2 & 32.3 计算 ~-22.4 计算 ~22.5 计算 1 >> 22.6 计算 1 << 23 补充:为什么计算机采用补码运算的方式

1 原码、反码与补码

1.1 概述

✈️在计算机的运算中,都是以补码的方式进行运算的,当我们要查看运算结果的时候需要看原码。(运算过程用补码,查看结果用原码)


原码 :最高位符号位,0代表正数,1代表负数,非符号位为该数字绝对值的二进制。

反码:正数的反码与原码一致,负数的反码是对原码按位取反,只是最高位(符号位)不变。

补码:正数的补码与原码一致,负数的补码是该数的反码加1。


1.2 规律及方法

🍎由于Java中无无符号数,因此这里讨论有符号数,对于有符号的而言:


⭐️ 二进制的最高位是符号位,0表示正数,1表示负数;

⭐️ 正数的原码、反码、补码都一样;

⭐️ 负数的反码 = 除符号位不变以外其余位取反(0变1,1变0);

⭐️ 负数的补码 = 该数的反码 + 1;

⭐️ 0的反码、补码都是0。

2 位运算符

2.1 位运算符概述

🍎 位运算符一览表:

符号 名称 运算
& 按位与 两位全为1,结果为1,否则为0
/(竖线) 按位或 两位有一个为1,结果为1,否则为0
^ 按位异或 两位一0一1则为1,反之为0
~ 按位取反 0变1,1变0
>> 算术右移 低位溢出,符号位不变,并用符号位补溢出的高位
<< 算术左移 符号位不变,低位补0
>>> 逻辑右移 / 无符号右移 低位溢出,高位补0


2.2 计算 2 & 3

🍎【推导】2 & 3 = 2


由于计算机是以补码的方式进行运算,所以在计算 2 & 3 时:


⭐️先得到 2 的原码,在Java 中 int 占4个字节,一个字节为8位,则 2 的补码为 00000000 00000000 00000000 00000010;

⭐️求出 2 的补码 :由于 2 是正数,则其 原码、补码、反码都是一致的,因此其补码为 00000000 00000000 00000000 00000010;

⭐️ 同理,我们可以求得 3 的补码 = 原码 为 00000000 00000000 00000000 00000011;

⭐️ 按位 & 后求得补码为 00000000 00000000 00000000 00000010;

⭐️ 前面提到,我们查看结果需要求原码,由补码求得原码为:00000000 00000000 00000000 00000010;

⭐️ 最终求得的原码转成十进制,答案为2。

🌟【结果验证】


System.out.println(2 & 3);  // 2
1

2.3 计算 ~-2

🍎【推导】~-2 = 1


1.⭐️ 先得到 -2 的原码(负数最高位为1): 10000000 00000000 00000000 00000010;

2.⭐️ 求 -2 的反码(除符号位,其余位取反): 11111111 11111111 11111111 11111101;

3.⭐️ 求 -2 的补码(补码 = 反码 + 1):11111111 11111111 11111111 11111110;

4.⭐️ 进行 ~ 取非运算:00000000 00000000 00000000 000000001;

5.⭐️ 由于取非操作后,最高位为0,表示正数,因此,该码即为运算结果的原码,对应转化成十进制数为1,故答案为1。


🌟【结果验证】

System.out.println(~-2);  // 1
1

2.4 计算 ~2

🍎【推导】~2 = -3


1.⭐️ 先得到 2 的补码(正数补码原码反码相同): 00000000 00000000 00000000 00000010;

2.⭐️ 进行 ~ 取非运算:11111111 11111111 11111111 111111101;

3.⭐️ 由于取非操作后,最高位为1,表示负数,因此,需要根据补码求对应的原码,在负数中,由于 补码 = 反码 + 1,我们可以求得反码(补码-1):11111111 11111111 11111111 111111100;

4.⭐️ 原码求得(符号位不变,其余位取反):10000000 00000000 00000000 00000011;

5.⭐️ 将原码转成十进制为 2,因此,答案为-3。


🌟【结果验证】

System.out.println(~2);  // -3
1

2.5 计算 1 >> 2

🍎 【推导】1 >> 2 = 0

✈️【本质】实际就是进行了 1 / 2 / 2 = 0的运算


1.⭐️ 1 对应的补码为 00000000 00000000 00000000 00000001;

2.⭐️ 进行 >> 运算,右移两位,低位溢出,高位用符号位补,得到: 00000000 00000000 00000000 00000000;

3.⭐️ 该补码对应的原码不变,转成十进制为0。


🌟【结果验证】

System.out.println(1 >> 2);  // 0
1

2.6 计算 1 << 2

🍎 【推导】1 << 2 = 4

✈️【本质】实际就是进行了 1 * 2 * 2 = 4的运算


1.⭐️ 1 对应的补码为 00000000 00000000 00000000 00000001;

2.⭐️ 进行 << 运算,左移两位,符号位不变,低位补0,得到: 00000000 00000000 00000000 00000100;

3.⭐️ 该补码对应的原码不变,转成十进制为4。


🌟【结果验证】

System.out.println(1 << 2);  // 4
1

3 补充:为什么计算机采用补码运算的方式

😎对于有符号数,内存要区分符号位和数值位,要是能把符号位和数值位等同起来,让它们一起参与运算,不再加以区分,只用加法器就可以同时实现加法和减法运算,这样硬件电路就变得简单了。


8 - 3 等价于 8 + (-3),12 - (-9) 等价于 10 + 9。


简化硬件电路的代价就是有符号数在存储和读取时都要进行转化。这个转换过程就涉及到我们熟悉的原码、反码、补码。


原码将一个整数转换成二进制形式,就是其原码。例如short a = 5;,a 的原码就是0000 0000 0000 0101;更改 a 的值a = -19;,此时 a 的原码就是1000 0000 0001 0011。


❤️ 通俗的理解,原码就是一个整数本来的二进制形式。


正数与负数的反码不一样。


对于正数,它的反码就是其原码(原码和反码相同);负数的反码是将原码中除符号位以外的所有位(数值位)取反,也就是 0 变成 1,1 变成 0。例如 short a = 5;,a 的原码和反码都是 0000 0000 0000 0101;更改 a 的值 a = -19;,此时 a 的反码是 1111 1111 1110 1100。


❓❓❓为什么需要反码?


答:反码的作用就相当于数学中的负数,有了负数,才可以实现减法与加法运算统一成加法运算。


❓❓❓有了反码为什么还需要补码?


答:因为 “0” 这个特殊数字的存在。


将减法运算按加法运算处理,负数需要用反码表示,那么用 8 位二进制反码表示的正数范围:+0 —— +127;负数范围:-127 —— -0。但是,其中有两个特殊的编码会出现:


[0_0000000]=+0 (反码)


[1_1111111]=-0 (反码)


+0 和 -0 代表的都是 0。这样一来,“0” 这个数字在计算机中的编码就不是唯一的了。对于计算机来说,这是绝对不行的,因为任何数字都只能有 1 个编码。


我们知道 0 既不是正数也不是负数,为了解决这个编码不唯一的问题,把 0 当成正数,也即 +0,这样 0 的编码就变成:0_0000000。那 8 位二进制表示的正数范围仍然是:+0 —— +127。负数整体向后“挪动1位”,反码 +1,{1_1111111}编码就不再表示 -0,而变成了 -1。顺着推,最小的编码{1_0000000}就是 -128,8 位二进制表示的负数范围从:-127 —— -0 变成:-128 —— -1,就能成功解决问题。(不要忽略了看结果需要转换成原码哦!!!)


相关文章
|
测试技术
CRC-16 MODBUS原理,附实测可用源码
之前做串口解析,CRC校验一直用和校验,就是吧各个位加在一起,新来一个串口协议,是CRC-16 MODBUS的形式校验,不会呀,从网上找了找资源,没有找到源码,都要下载,分享出来。
CRC-16 MODBUS原理,附实测可用源码
|
XML JSON 前端开发
@RestController和@Controller的区别
【9月更文挑战第18天】@RestController和@Controller的区别
882 5
|
安全 Java 网络安全
Java Socket编程教程:构建安全可靠的客户端-服务器通信
【6月更文挑战第21天】构建安全的Java Socket通信涉及SSL/TLS加密、异常处理和重连策略。示例中,`SecureServer`使用SSLServerSocketFactory创建加密连接,而`ReliableClient`展示异常捕获与自动重连。理解安全意识,如防数据截获和中间人攻击,是首要步骤。通过良好的编程实践,确保网络应用在复杂环境中稳定且安全。
253 0
|
安全 容器
win10删除文件时权限不够(你需要来自Administrators 的权限才能对此文件进行更改,无法枚举容器的对象,访问被拒绝)
win10删除文件时权限不够(你需要来自Administrators 的权限才能对此文件进行更改,无法枚举容器的对象,访问被拒绝)
7589 0
win10删除文件时权限不够(你需要来自Administrators 的权限才能对此文件进行更改,无法枚举容器的对象,访问被拒绝)
|
JavaScript Apache 容器
如何使用ECharts制作一个简单的柱状图
如何使用ECharts制作一个简单的柱状图
395 0
|
12月前
|
机器学习/深度学习 计算机视觉 异构计算
YOLOv8优改系列一:YOLOv8融合BiFPN网络,实现网络快速涨点
该专栏专注于YOLOv8的 Neck 部分改进,融合了 BiFPN 网络,大幅提升检测性能。BiFPN 通过高效的双向跨尺度连接和加权特征融合,解决了传统 FPN 的单向信息流限制。文章详细介绍了 BiFPN 的原理及其实现方法,并提供了核心代码修改指导。点击链接订阅专栏,每周定时更新,助您快速提升模型效果。推荐指数:⭐️⭐️⭐️⭐️,涨点指数:⭐️⭐️⭐️⭐️。
902 0
|
SQL 数据采集 存储
Hive实战 —— 电商数据分析(全流程详解 真实数据)
关于基于小型数据的Hive数仓构建实战,目的是通过分析某零售企业的门店数据来进行业务洞察。内容涵盖了数据清洗、数据分析和Hive表的创建。项目需求包括客户画像、消费统计、资源利用率、特征人群定位和数据可视化。数据源包括Customer、Transaction、Store和Review四张表,涉及多个维度的聚合和分析,如按性别、国家统计客户、按时间段计算总收入等。项目执行需先下载数据和配置Zeppelin环境,然后通过Hive进行数据清洗、建表和分析。在建表过程中,涉及ODS、DWD、DWT、DWS和DM五层,每层都有其特定的任务和粒度。最后,通过Hive SQL进行各种业务指标的计算和分析。
2517 1
Hive实战 —— 电商数据分析(全流程详解 真实数据)
|
数据可视化
Echarts动态数据可视化学习(2)柱状图和折线图的动态数据更新
Echarts动态数据可视化学习(2)柱状图和折线图的动态数据更新
391 0
|
存储 Java Maven
IntelliJ IDEA - 生成 iml 文件
IntelliJ IDEA - 生成 iml 文件
2559 0
IntelliJ IDEA - 生成 iml 文件
MFC打开控制台的2种方式
MFC打开控制台的2种方式
429 0