2015-01-29
环境:jdk 1.7。
Java的位运算(Bitwise operation)直接对整数类型的位进行操作,这些整数类型包括long、int、short、char和 byte。
在java中:
byte -> 8 bits
short -> 16 bits
int -> 32 bits
long -> 64 bits
char -> 16 bit
int的位运算
基础
在java中,int数据底层以补码形式存储。关于原码、反码、补码,《原码, 反码, 补码 详解》给出了很精彩的解释。
int型变量使用32bit存储数据,其中最高位是符号位,0表示正数,1表示负数。例如:
// 若最高的几位为0则不输出这几位,从为1的那一位开始输出
System.out.println(Integer.toBinaryString(10));
System.out.println(Integer.toBinaryString(-10));
会输出(手工排版过,以下的输出均会被手工排版):
1010
11111111111111111111111111110110
加法运算1:
System.out.println(Integer.toBinaryString(11));
System.out.println(Integer.toBinaryString(10));
System.out.println(Integer.toBinaryString(21));
输出:
1011
1010
10101
加法运算2:
System.out.println(Integer.toBinaryString(-11));
System.out.println(Integer.toBinaryString(-10));
System.out.println(Integer.toBinaryString(-21));
输出:
11111111111111111111111111110101
11111111111111111111111111110110
11111111111111111111111111101011
加法运算3:
System.out.println(Integer.toBinaryString(11));
System.out.println(Integer.toBinaryString(-10));
System.out.println(Integer.toBinaryString(1));
输出:
1011
11111111111111111111111111110110
1
加法运算4:
System.out.println(Integer.toBinaryString(-11));
System.out.println(Integer.toBinaryString(10));
System.out.println(Integer.toBinaryString(-1));
输出:
11111111111111111111111111110101
1010
11111111111111111111111111111111
对于2进制补码的加法运算,和平常的计算一样,而且符号位也参与运算,不过最后只保留32位。
左移<<
System.out.println(Integer.toBinaryString(11));
System.out.println(Integer.toBinaryString(11<<2)); // 左移2位,44
System.out.println(Integer.toBinaryString(11<<28)); // -1342177280,负数
System.out.println(Integer.toBinaryString(-11));
System.out.println(Integer.toBinaryString(-11<<2)); // -44
输出:
1011
101100
10110000000000000000000000000000
11111111111111111111111111110101
11111111111111111111111111010100
可以看出符号位也参与移位,移位时右侧空出的位补0。
右移>>
System.out.println(Integer.toBinaryString(11));
System.out.println(Integer.toBinaryString(11>>2)); // 2
System.out.println(Integer.toBinaryString(-11));
System.out.println(Integer.toBinaryString(-11>>2)); // -3
输出:
1011
10
11111111111111111111111111110101
11111111111111111111111111111101
对于右移,符号位参与移位。对于正数而言空出的位置补0,负数则补1。
无符号右移 >>>
System.out.println(Integer.toBinaryString(11));
System.out.println(Integer.toBinaryString(11>>>2)); // 2
System.out.println(Integer.toBinaryString(-11));
System.out.println(Integer.toBinaryString(-11>>>2)); // 1073741821
输出:
1011
10
11111111111111111111111111110101
111111111111111111111111111101
对于无符号右移,符号位参与移位。对于正数和负数,空出的位置均补0。
与运算
System.out.println(Integer.toBinaryString(11));
System.out.println(Integer.toBinaryString(10));
System.out.println(Integer.toBinaryString(11 & 10));
System.out.println(Integer.toBinaryString(-11));
System.out.println(Integer.toBinaryString(10));
System.out.println(Integer.toBinaryString(-11 & 10));
输出:
1011
1010
1010
11111111111111111111111111110101
1010
0
或运算
System.out.println(Integer.toBinaryString(11));
System.out.println(Integer.toBinaryString(10));
System.out.println(Integer.toBinaryString(11 | 10));
System.out.println(Integer.toBinaryString(-11));
System.out.println(Integer.toBinaryString(10));
System.out.println(Integer.toBinaryString(-11 | 10));
输出:
1011
1010
1011
11111111111111111111111111110101
1010
11111111111111111111111111111111
异或运算
System.out.println(Integer.toBinaryString(11));
System.out.println(Integer.toBinaryString(10));
System.out.println(Integer.toBinaryString(11 ^ 10));
System.out.println(Integer.toBinaryString(-11));
System.out.println(Integer.toBinaryString(10));
System.out.println(Integer.toBinaryString(-11 ^ 10));
输出:
1011
1010
1
11111111111111111111111111110101
1010
11111111111111111111111111111111
非运算
System.out.println(Integer.toBinaryString(11));
System.out.println(Integer.toBinaryString(~11));
System.out.println(Integer.toBinaryString(-11));
System.out.println(Integer.toBinaryString(~-11));
输出:
1011
11111111111111111111111111110100
11111111111111111111111111110101
1010
long的位运算
和int类似,就是位数变成了64bit。举个例子:
System.out.println(Long.toBinaryString(-10L));
System.out.println(Long.toBinaryString(-10L<<2));
输出:
1111111111111111111111111111111111111111111111111111111111110110
1111111111111111111111111111111111111111111111111111111111011000
byte、short、char的位运算
先被拓宽为int类型,然后进行位运算。类Short
、Character
、Byte
中也没有toBinaryString
方法。例如:
short i;
byte b;
i = 5;
System.out.println(Integer.toBinaryString(i));
System.out.println(Integer.toBinaryString(i<<2));
i = -5;
System.out.println(Integer.toBinaryString(i));
System.out.println(Integer.toBinaryString(i<<2));
b = -128;
System.out.println(Integer.toBinaryString(b));
System.out.println(Integer.toBinaryString(b<<2));
输出:
101
10100
11111111111111111111111111111011
11111111111111111111111111101100
11111111111111111111111110000000
11111111111111111111111000000000
不止这些
对于移位运算,例如将x左移/右移n位,如果x是byte、short、char、int,n会先模32(即n=n%32),然后再进行移位操作。可以这样解释:int类型为32位,移动32位(或以上)没有意义。
同理若x是long,n=n%64。