1.按位运算符
按位运算符 允许我们操作二进制位 会对两个自变量中对应的位执行布尔代数 并最终生成一个结果。
源于C语言的低级操作,要直接操作硬件,需要频繁设置硬件寄存器内的二进制位。
java设计初衷就是为了嵌入电视机顶盒内,所以这种低级操作保留下来了。
然而 由于操作系统的进步,现在不必过于频繁进行按位运算
若两个输入位都是 1,则按位 AND 运算符( &)在输出位里生成一个 1;否则生成 0。若两个输入位里至少有
一个是 1,则按位 OR 运算符( |)在输出位里生成一个 1;只有在两个输入位都是 0 的情况下,它才会生成一
个 0。若两个输入位的某一个是 1,但不全都是 1,那么按位 XOR( ^,异或)在输出位里生成一个 1
AND 运算符( &)
OR 运算符( |)
XOR( ^,异或)
~ NOT非运算符
只对一个自变量操作
按位 NOT 生成与输入位的相反的值—— 若输入 0,则输出 1;输入 1,则输出 0
与=联合使用
&=, |=和^=
boolean(布尔)类型
可执行按位 AND, OR 和 XOR
针对布尔值进行的按位运算为我们新
增了一个 XOR 逻辑运算符,它并未包括在“逻辑”运算符的列表中。在移位表达式中,我们被禁止使用布尔运算
2.移位运算符
可单独用它们处理整数类型
左移位运算符( <<)
将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补 0)
“有符号”右移位运算符( >>)
将运算符左边的运算对象向右移动运算符右侧指定的位数。
使用了“符号扩展”:若值为正,则在高位插入 0;若值为负,则在高位插入 1。
“无符号”右移位运算符( >>>)
使用了“零扩展”:无论正负,都在高位插入0。这一运算符是 C 或 C++没有的。
若对 byte 或 short 值进行右移位运算,得到的可能不是正确的结果
( Java 1.0 和 Java 1.1 特别突出)
它们会自动转换成 int 类型,并进行右移位。但“零扩展”不会发
生,所以在那些情况下会得到-1 的结果。
//: BitManipulation.java
// Using the bitwise operators
import java.util.*;
public class BitManipulation {
public static void main(String[] args) {
Random rand = new Random();
int i = rand.nextInt();
int j = rand.nextInt();
pBinInt("-1", -1);
pBinInt("+1", +1);
int maxpos = 2147483647;
pBinInt("maxpos", maxpos);
int maxneg = -2147483648;
pBinInt("maxneg", maxneg);
pBinInt("i", i);
pBinInt("~i", ~i);
pBinInt("-i", -i);
pBinInt("j", j);
pBinInt("i & j", i & j);
pBinInt("i | j", i | j);
pBinInt("i ^ j", i ^ j);
pBinInt("i << 5", i << 5);
pBinInt("i >> 5", i >> 5);
pBinInt("(~i) >> 5", (~i) >> 5);
pBinInt("i >>> 5", i >>> 5);
pBinInt("(~i) >>> 5", (~i) >>> 5);
long l = rand.nextLong();
long m = rand.nextLong();
pBinLong("-1L", -1L);
pBinLong("+1L", +1L);
long ll = 9223372036854775807L;
pBinLong("maxpos", ll);
long lln = -9223372036854775808L;
pBinLong("maxneg", lln);
pBinLong("l", l);
pBinLong("~l", ~l);
pBinLong("-l", -l);
pBinLong("m", m);
pBinLong("l & m", l & m);
pBinLong("l | m", l | m);
pBinLong("l ^ m", l ^ m);
pBinLong("l << 5", l << 5);
pBinLong("l >> 5", l >> 5);
pBinLong("(~l) >> 5", (~l) >> 5);
pBinLong("l >>> 5", l >>> 5);
pBinLong("(~l) >>> 5", (~l) >>> 5);
}
static void pBinInt(String s, int i) {
System.out.println(
s + ", int: " + i + ", binary: ");
System.out.print(" ");
for (int j = 31; j >= 0; j--)
if (((1 << j) & i) != 0)
System.out.print("1");
else
System.out.print("0");
System.out.println();
}
static void pBinLong(String s, long l) {
System.out.println(
s + ", long: " + l + ", binary: ");
System.out.print(" ");
for (int i = 63; i >= 0; i--)
if (((1L << i) & l) != 0)
System.out.print("1");
else
System.out.print("0");
System.out.println();
}
} ///:~
数字的二进制形式表现为“有符号 2 的补值”
移位可与等号( <<=或>>=或>>>=)组合使用。此时,运算符左边的值会移动由右边的值指定的位数,再将得到的结果赋回左边的值。
下面这个例子向大家阐示了如何应用涉及“按位”操作的所有运算符,以及它们的效果:
注意,若对 char, byte 或者 short 进行移位处理,那么在移位进行之前,它们会自动转换成一个 int
只有右侧的5 个低位才会用到,可防止我们在一个 int 数里移动不切实际的位数
若对一个 long 值进行处理,最后得到的结果也是 long。此时只会用到右侧的 6 个低位,防止移动超过 long 值里现成的位数
参考资料:
《Thinking in java 4》