Java - 位运算
原码:将最高位作为符号位(以0代表正、1代表负),其余的各位代表本身的绝对值(以二进制表示)。
+7 原码为:00000111
-7 原码为:10000111
反码:一个数为正,则它的反码与原码相同;一个数为负,则符号位为1,其余各位是原码取反。(0->1,1->0)
+7 反码为:00000111
-7 反码为:11111000
补码:一个数若为负,则其补码为其反码+1;正数的原码、反码、补码相同。
-7 补码为:11111001
对有符号而言:
- 二进制最高位是符号位,0为正数、1为负数。
- 正数的原码、反码、补码都一样。
- 负数的反码 = 它的原码符号位不变,其它位取反。
- 负数的补码 = 它的反码 + 1。
- 0 的反码、补码都是 0 。
- Java 的数都是有有符号的。
- 计算机运算时,都是以补码的方式运算的,可以避免 +0 与 -0 的二进制表示方式不同。
(1-2)位运算:1 - 2 = 1 + (-2)
1的补码:00000001 -2的原码:10000010 -> 反码:11111101 -> 补码:11111110
0 0 0 0 0 0 0 1
+ 1 1 1 1 1 1 1 0
———————————
1 1 1 1 1 1 1 1
求得的结果是补码。由于最高位是1,说明是负数。负数的原码与补码不同,需要转换。
补码:11111111 -> 反码=补码-1:11111110 -> 原码=反码最高位不变,其它取反:10000001,结果为 -1 。
Java 位运算符:~(按位取反)、^(按位异或)、&(按位与)、|(按位或)
&(按位与):两位全为 1 ,结果为 1 。
0 1 1 0 1 1 0 1
& 0 0 1 1 0 1 1 1
———————————
0 0 1 0 0 1 0 1
|(按位或):两位有一个为 1 ,结果为 1 。
0 1 1 0 1 1 0 1
& 0 0 1 1 0 1 1 1
———————————
0 1 1 1 1 1 1 1
^(按位异或):两位有一个为 1 ,另一个为 0 , 结果为 1 。
0 1 1 0 1 1 0 1
^ 0 0 1 1 0 1 1 1
———————————
0 1 0 1 1 0 1 0
~(按位取反):0 -> 1 , 1 -> 0 。
~ 0 1 1 0 1 1 0 1
———————————
1 0 0 1 0 0 1 0 --------> -18
注意:以上的算术都是以补码的形式运算。
Java 中三个移位运算符:<<(算术左移、左移)、>>(算术右移、带符号右移)、>>>(逻辑右移、不带符号右移动)
<<(算术左移、左移):符号位不变,低位补 0 。
17 << 2 :00010001 —> 01000100
-17 << 2 :11101111 —> 10111100
>>(算术右移、带符号右移):低位溢出,符号位不变,并用符号位补溢出的高位。(负数带符号移动,前面不足加1。)
17 >> 2 :00010001 —> 00000100
-17 >> 2 :11101111 —> 11111011
>>>(逻辑右移、不带符号右移动):低位溢出,高位补 0 。(正数不带符号右移与带符号右移相同,负数前面不足加0。)
17 >> 2 :00010001 —> 00000100
-17 >> 2 :11101111 —> 00111011