文章目录
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
🌟【结果验证】
System.out.println(2 & 3); // 2
2.3 计算 ~-2
🍎【推导】~-2 = 1
🌟【结果验证】
System.out.println(~-2); // 1
2.4 计算 ~2
🍎【推导】~2 = -3
🌟【结果验证】
System.out.println(~2); // -3
2.5 计算 1 >> 2
🍎 【推导】1 >> 2 = 0
✈️【本质】实际就是进行了 1 / 2 / 2 = 0的运算
🌟【结果验证】
System.out.println(1 >> 2); // 0
2.6 计算 1 << 2
🍎 【推导】1 << 2 = 4
✈️【本质】实际就是进行了 1 * 2 * 2 = 4的运算
🌟【结果验证】
System.out.println(1 << 2); // 4
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,就能成功解决问题。(不要忽略了看结果需要转换成原码哦!!!)