学习目录:
- 按位左移运算符的工作原理
- 二进制补码表示法
- 二进制加减法
- 理解借位操作
在 Java 中,<<
是按位左移运算符,用于将数字的二进制位向左移动指定的位数。
对于负数,按位左移运算符也有其特定的作用。它会将负数的二进制表示左移,同时在右侧填充零。
一. 按位左移运算符的工作原理:
- 按位左移运算符 (
<<
) 会将数字的二进制表示向左移动指定的位数。 - 左移时,符号位保持不变,并且空出的右边部分用零填充。
- 对于负数,
<<
操作会影响二进制表示,符号位可能会发生变化,从而影响最终的值。
例子:
假设我们对一个负数进行左移操作
1 | public class BitwiseShift { |
解释:
a = -4
的二进制表示是11111111111111111111111111111100
(32 位补码表示)。- 执行
a << 2
时,数字-4
的二进制表示左移了 2 位,得到的是11111111111111111111111111110000
(即 -16 的补码表示)。 - 所以,左移后的结果是
-16
。
关键点:
- 对于负数,按位左移时符号位(最左边的 1)可能会被扩展到新的位置,因此最终的值可能会变得更负。
- 负数的左移操作会改变二进制表示的符号和大小,因此它可能不会像对正数的移位那样直观。
在 Java 中,负数通常使用 32 位补码表示,即使你使用的数据类型是 byte
、short
、int
或 long
,它们也会根据相应的大小采用补码表示法。
对于 int
类型,负数的补码表示是 32 位的。
对于 long
类型,负数的补码表示是 64 位的。
二. 二进制补码表示法
计算 -4 的二进制表示法,步骤:
1. 计算 4
的二进制表示:
首先,计算 4
的二进制表示。4
的二进制表示是:
1 | 00000000 00000000 00000000 00000100 |
这里假设使用的是 32 位有符号整数表示(即 4 字节)。4
的二进制是 00000000 00000000 00000000 00000100
,因为 4
的二进制表示为 100
,前面补充了 0 以满足 32 位表示。
2. 求 -4
的二进制表示:
要得到负数 -4
的二进制补码表示,需要按照以下步骤操作:
步骤 1:将 4
的二进制取反(得到反码):
4
的二进制是 00000000 00000000 00000000 00000100
,取反后得到反码:
1 | 11111111 11111111 11111111 11111011 |
步骤 2:反码加 1,得到 -4 补码:
1 | 11111111 11111111 11111111 11111100 |
三. 二进制加法
在二进制中,1 + 1
的计算结果与我们在十进制中的加法类似,但它遵循二进制的规则
二进制加法规则:
0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
- **
1 + 1 = 10
**(即 1 + 1 会进位,结果是 0,进位 1)
例:1+1+1=?
解:1+1=10 ,10+1=11
四. 二进制减法
在二进制减法中,操作过程与十进制减法类似,但由于只有 0 和 1 两个数字,借位的规则也有一些不同。
1. 二进制减法的基本规则:
- 0 - 0 = 0
没有借位 - 1 - 0 = 1
没有借位 - 1 - 1 = 0
没有借位 - 0 - 1 = 1 (需要借位)
由于0
不足以减去1
,需要从高位借位。借位的规则是:借 1,相当于从高位借来2(两个1)
,然后0
变为2两个1
,再减去1
,结果是1
。
五. 借位操作
借位操作是二进制减法中的一个重要概念。当进行二进制减法时,如果某一位的被减数小于减数,就需要进行借位操作,就像在十进制减法中一样。由于二进制只有 0
和 1
两个数字,因此借位的规则与十进制略有不同。
借位的基本规则:
- 如果当前位的被减数为
0
,而减数为1
,就需要从高位借位。 - 借位后,当前位的
0
变为10
(即二进制的2
,在简单点讲就是两个1),然后再进行减法。
例题:
1 | 1010 |
- 从最右边开始:
0 - 1
,需要借位。因为0
不足以减去1
,所以向左借位。
- 借位后:
- 借位之后,原来
0
变成10
(即2
,也就是两个1
)。所以10 - 1 = 1
相当于1-1-1=1
,结果为1
- 接着处理第二位:
- 原来的
1
变成0
(因为已经借位)。现在,0 - 1
,仍然需要借位。 - 借位后,
0
变成10
(即2(两个1)
),然后10 - 1 = 1(1-1-1=1)
,结果为1
第二借第三,因为第三位为0,无法借,第三位就先借第四位的1,变成了 10
,即 2
(或说两个 1
),第三然后借了其中一个1
给第二位,第三位剩 1
,第二位就变成了10-1=1(1-1-1=1)
,最后第三位为1
,第四位为0
- 接着第三位:
由于第三位已经借了前一位后成2(两个1)
,又借给第二位一个1
,所以第三位还剩下1
,计算得:1-1=0
- 接着第四位:
已经借出去了,第四位为0
,计算得:0-0=0
六. 负数左移的常见应用场景:
- 乘法运算: 对负数进行左移相当于将其乘以 2 的幂。左移
n
位就是将该数乘以2^n
。例如,-3 << 1
相当于-3 * 2 = -6
,-3 << 2
相当于-3 * 4 = -12
。 - 符号扩展: 左移操作会扩展符号位,使得负数的绝对值增加。由于负数的补码形式,左移时符号位可能会受到影响,这使得左移可以用来操作数字的大小,特别是在对二进制数进行位操作时。
- 实现位图或位标志操作: 在一些应用中,负数可能会作为标志位来表示不同的状态或标识。通过左移负数的位,可以有效地表示更大的数值范围。例如,使用负数进行左移操作,往往是在位图操作中使用,用来设置或清除特定的标志位。