<span style="font-size:14px;">位运算,顾名思义对位进行操作,计算机中所有信息都是二进制数,则为对二进制数位进行操作。
1.Java在处理整数数值的时候,可以直接对整数数值的二进制位进行操作。位运算包括:
&(与)、|(或)、^(异或)、~(非)、>>(带符号左移)、<<(带符号右移位)、>>>(无符号左移)。
二进制中只含0和1两个数字,可以简单的理解成0=false、1=true。不过在Java中的boolean类型和数值没有关系,
只是这样可以帮助理解记忆,因为离散中的逻辑运算和这个是类似的。
例:00001100&00011010=00001000,Java中不能直接表示二进制最形象的方式就是表示成12进制。
把上例变成16进制就是:0x0000000c&0x0000001a=0x00000008。
代码是:
System.out.println(Integer.toBinaryString(0x0000000c));
System.out.println(Integer.toBinaryString(0x0000001a));
System.out.println(Integer.toBinaryString(0x0000000c& 0x0000001a) );
把&分别换成其它符号看下结果。
^运算比较难记,对应位值相同结果是0,不同是1。
"<<"将二进制位右移。">>"和">>>"将二进制位右移,不同之处是">>"用符号位填充高位,">>>"用0来填充。
2.Java中的位运算也可以应用在boolean型上面。运算结果和逻辑元算相同得到的结果也是boolean值,
只不过不按“短路”方式进行计算。
位运算直接对底层进行操作,一直感觉在Java中没有太大的用处。但是在使用Class类的时候无意发现了位运算的应用,设计挺巧妙。
java.lang.Class类中的Modifiers()方法可以获得修饰符对应的整型代码。
例如:
Class c =Class.forName("java.lang.Integer");
System.out.println(c.getModifiers());
打印出整数值17。
在java.lang.reflect.Modifier中定义了Java修饰符与整数值的对应。
ABSTRACT 1024
FINAL 16
INTERFACE 512
NATIVE 256
PRIVATE 2
PROTECTED 4
PUBLIC 1
STATIC 8
STRICT 8
SYNCHRONIZED 32
TRANSIENT 128
VOLATILE 64
对应表中也并没有17。表中一个整数对应一个修饰符,类java.lang.Integer的修饰符是publicfinal,两个修饰符,
如何使用一个整数来表示两个修饰符哪?百思不得其解,于是看了源码,恍然大悟。
public static final int PUBLIC= 0x00000001;
public static final int PRIVATE= 0x00000002;
public static final intPROTECTED = 0x00000004;
public static final int STATIC= 0x00000008;
public static final int FINAL= 0x00000010;
public static final int SYNCHRONIZED = 0x00000020;
public static final int VOLATILE= 0x00000040;
public static final int TRANSIENT= 0x00000080;
public static final int NATIVE= 0x00000100;
public static final int INTERFACE= 0x00000200;
public static final intABSTRACT = 0x00000400;
public static final int STRICT= 0x00000800;
17显然是1和16的和。1代表了PUBLIC,16代表了FINAL。写成16进制要好看一些:
1 =0x00000001
+ 16=0x00000010
------------------
17=0x00000011
观察数字格式,估计已经明白了一半。
再看java.lang.Integer中的isPublic()和isFinal()方法
public static boolean isPublic(intmod) {
return(mod & PUBLIC) != 0;
}
public static boolean isFinal(intmod) {
return(mod & FINAL) != 0;
}
还有在Java标准类库中对大于0小于0的判断,也基本使用的是位运算。
例如在java.util.zip.DeflaterOutputStream中voidwrite(byte[] b, int off, int len)方法
@Override
public voidwrite(byte[] b, int off, int len) throws IOException {
if (def.finished()) {
throw new IOException("write beyond end of stream");
}
if ((off | len | (off + len) |(b.length - (off + len))) < 0){
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
if (!def.finished()) {
// Deflate no more than stride bytes at a time. This avoids
// excess copying in deflateBytes (see Deflater.c)
int stride = buf.length;
for (int i = 0; i < len; i += stride) {
def.setInput(b, off + i, Math.min(stride, len - i));
while (!def.needsInput()) {
deflate();
}
}
}
}
判断数组下标合法的那段。
它们都应用了位运算,简练、高效!</span>
JAVA位元算的应用
最新推荐文章于 2025-05-12 22:11:53 发布