【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,就能成功解决问题。(不要忽略了看结果需要转换成原码哦!!!)


相关文章
|
6月前
|
Java 程序员
Java基础之原码,反码,补码,位运算符
Java基础之原码,反码,补码,位运算符
|
1月前
深入解析计算机科学的基础:原码、反码与补码
深入解析计算机科学的基础:原码、反码与补码
|
3月前
|
存储 Oracle Java
01 Java概述基础与计算机基础(DOS+进制+原码反码补码)
01 Java概述基础与计算机基础(DOS+进制+原码反码补码)
43 17
反码与补码的概念及其在计算机中的应用
反码与补码的概念及其在计算机中的应用
|
5月前
|
存储 C语言
【C语言进阶篇】整数在内存的存储——原码、反码、补码
【C语言进阶篇】整数在内存的存储——原码、反码、补码
|
Java
Java 中位运算,原码,反码,补码的详解
Java 中位运算,原码,反码,补码的详解
106 0
【软考学习2】数据表示——原码 反码 补码 移码
【软考学习2】数据表示——原码 反码 补码 移码
137 0
|
6月前
|
存储 Java
JavaSE - 原码,反码,补码和>>以及>>>
JavaSE - 原码,反码,补码和>>以及>>>
83 0
|
存储 IDE Java
二进制到汇编:进制,原码反码补码,位运算,通用寄存器,内存一套打通
二进制到汇编:进制,原码反码补码,位运算,通用寄存器,内存一套打通
177 1
数字逻辑基础:原码、反码、补码
数字逻辑基础:原码、反码、补码
184 0