Skip to content

Commit 55df968

Browse files
committed
更新移位运算符
1 parent 7e14c42 commit 55df968

File tree

1 file changed

+159
-0
lines changed

1 file changed

+159
-0
lines changed

docs/book/04-Operators.md

+159
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,165 @@ float f4 = 1e-47f; //10 的幂数
660660
## 移位运算符
661661

662662

663+
移位运算符面向的运算对象也是二进制的“位”。可单独用它们处理整数类型(基本类型的一种)。左移位运算符 `<<` 能将其左边的运算对象向左移动右侧指定的位数(在低位补 0)。右移位运算符 `>>` 则相反。位移运算符有“正”、“负”值”:若值为正,则在高位插入 0;若值为负,则在高位插入 1。Java 也添加了一种“不分正负”的右移位运算符(>>>),它使用了“零扩展”(**zero extension**):无论正负,都在高位插入 0。这一运算符是 C/C++ 没有的。
664+
665+
如果移动 **char****byte****short**,则会在移动发生之前将其提升为 **int**,结果为 **int**。仅使用右侧的 5 个低阶位。这可以防止我们移动超过 **int** 范围的位数。若对一个 **long** 值进行处理,最后得到的结果也是 **long**
666+
667+
668+
移位可以与等号 `<<=``>>=``>>>=` 组合使用。左值被替换为其移位运算后的值。但是,问题来了,当无符号右移与赋值相结合时,若将其与 **byte****short** 一起使用的话,则结果错误。取而代之的是,它们被提升为 **int** 型并右移,但在重新赋值时被截断。在这种情况下,结果为 -1。下面是代码示例:
669+
670+
```java
671+
// operators/URShift.java
672+
// 测试无符号右移
673+
public class URShift {
674+
public static void main(String[] args) {
675+
int i = -1;
676+
System.out.println(Integer.toBinaryString(i));
677+
i >>>= 10;
678+
System.out.println(Integer.toBinaryString(i));
679+
long l = -1;
680+
System.out.println(Long.toBinaryString(l));
681+
l >>>= 10;
682+
System.out.println(Long.toBinaryString(l));
683+
short s = -1;
684+
System.out.println(Integer.toBinaryString(s));
685+
s >>>= 10;
686+
System.out.println(Integer.toBinaryString(s));
687+
byte b = -1;
688+
System.out.println(Integer.toBinaryString(b));
689+
b >>>= 10;
690+
System.out.println(Integer.toBinaryString(b));
691+
b = -1;
692+
System.out.println(Integer.toBinaryString(b));
693+
System.out.println(Integer.toBinaryString(b>>>10));
694+
}
695+
}
696+
```
697+
698+
输出结果:
699+
700+
```
701+
11111111111111111111111111111111
702+
1111111111111111111111
703+
1111111111111111111111111111111111111111111111111111111
704+
111111111
705+
111111111111111111111111111111111111111111111111111111
706+
11111111111111111111111111111111
707+
11111111111111111111111111111111
708+
11111111111111111111111111111111
709+
11111111111111111111111111111111
710+
11111111111111111111111111111111
711+
1111111111111111111111
712+
```
713+
714+
715+
在上例中,结果并未重新赋值给变量 **b** ,而是直接打印出来,因此一切正常。下面是一个涉及所有位运算符的代码示例:
716+
717+
```java
718+
// operators/BitManipulation.java
719+
// 使用位运算符
720+
import java.util.*;
721+
public class BitManipulation {
722+
public static void main(String[] args) {
723+
Random rand = new Random(47);
724+
int i = rand.nextInt();
725+
int j = rand.nextInt();
726+
printBinaryInt("-1", -1);
727+
printBinaryInt("+1", +1);
728+
int maxpos = 2147483647;
729+
printBinaryInt("maxpos", maxpos);
730+
int maxneg = -2147483648;
731+
printBinaryInt("maxneg", maxneg);
732+
printBinaryInt("i", i);
733+
printBinaryInt("~i", ~i);
734+
printBinaryInt("-i", -i);
735+
printBinaryInt("j", j);
736+
printBinaryInt("i & j", i & j);
737+
printBinaryInt("i | j", i | j);
738+
printBinaryInt("i ^ j", i ^ j);
739+
printBinaryInt("i << 5", i << 5);
740+
printBinaryInt("i >> 5", i >> 5);
741+
printBinaryInt("(~i) >> 5", (~i) >> 5);
742+
printBinaryInt("i >>> 5", i >>> 5);
743+
printBinaryInt("(~i) >>> 5", (~i) >>> 5);
744+
long l = rand.nextLong();
745+
long m = rand.nextLong();
746+
printBinaryLong("-1L", -1L);
747+
printBinaryLong("+1L", +1L);
748+
long ll = 9223372036854775807L;
749+
printBinaryLong("maxpos", ll);
750+
long lln = -9223372036854775808L;
751+
printBinaryLong("maxneg", lln);
752+
printBinaryLong("l", l);
753+
printBinaryLong("~l", ~l);
754+
printBinaryLong("-l", -l);
755+
printBinaryLong("m", m);
756+
printBinaryLong("l & m", l & m);
757+
printBinaryLong("l | m", l | m);
758+
printBinaryLong("l ^ m", l ^ m);
759+
printBinaryLong("l << 5", l << 5);
760+
printBinaryLong("l >> 5", l >> 5);
761+
printBinaryLong("(~l) >> 5", (~l) >> 5);
762+
printBinaryLong("l >>> 5", l >>> 5);
763+
printBinaryLong("(~l) >>> 5", (~l) >>> 5);
764+
}
765+
766+
static void printBinaryInt(String s, int i) {
767+
System.out.println(
768+
s + ", int: " + i + ", binary:\n " +
769+
Integer.toBinaryString(i));
770+
}
771+
772+
static void printBinaryLong(String s, long l) {
773+
System.out.println(
774+
s + ", long: " + l + ", binary:\n " +
775+
Long.toBinaryString(l));
776+
}
777+
}
778+
```
779+
780+
输出结果(前 32 行):
781+
782+
```
783+
-1, int: -1, binary:
784+
11111111111111111111111111111111
785+
+1, int: 1, binary:
786+
1
787+
maxpos, int: 2147483647, binary:
788+
1111111111111111111111111111111
789+
maxneg, int: -2147483648, binary:
790+
10000000000000000000000000000000
791+
i, int: -1172028779, binary:
792+
10111010001001000100001010010101
793+
~i, int: 1172028778, binary:
794+
1000101110110111011110101101010
795+
-i, int: 1172028779, binary:
796+
1000101110110111011110101101011
797+
j, int: 1717241110, binary:
798+
1100110010110110000010100010110
799+
i & j, int: 570425364, binary:
800+
100010000000000000000000010100
801+
i | j, int: -25213033, binary:
802+
11111110011111110100011110010111
803+
i ^ j, int: -595638397, binary:
804+
11011100011111110100011110000011
805+
i << 5, int: 1149784736, binary:
806+
1000100100010000101001010100000
807+
i >> 5, int: -36625900, binary:
808+
11111101110100010010001000010100
809+
(~i) >> 5, int: 36625899, binary:
810+
10001011101101110111101011
811+
i >>> 5, int: 97591828, binary:
812+
101110100010010001000010100
813+
(~i) >>> 5, int: 36625899, binary:
814+
10001011101101110111101011
815+
...
816+
```
817+
818+
819+
结尾的两个方法 **printBinaryInt()****printBinaryLong()** 它们分别操作一个 **int****long** 值,并转换为二进制格式输出,同时附有简要的说明文字。除了演示 **int****long** 的所有位运算符的效果之外,本示例还显示 **int****long** 的最小值、最大值、+1 和 -1 值,以便我们了解它们的形式。注意高位代表符号:0 表示正,1 表示负。上面显示了 **int** 部分的输出。数字的二进制表示称为有符号的两个补数。
820+
821+
663822
<!-- Ternary-if-else-Operator -->
664823
## 三元运算符
665824

0 commit comments

Comments
 (0)