Java review(9) 位运算
很少人会用Java写位运算吧,也许有的人想到这么底层的东西会觉得可能只有c支持,但是Java的位运算和c基本是类似的。
@Test
public void test1() throws Exception {
Byte b1 = Byte.parseByte("-1110101", 2);
System.out.println("b1: " + b1 + " " + Integer.toBinaryString(b1));
Byte b2 = Byte.parseByte("1110101", 2);
System.out.println("b2: " + b2 + " " + Integer.toBinaryString(b2));
int b3 = b1 | b2;
System.out.println("b1 | b2: " + b3 + " " + Integer.toBinaryString(b3));
b3 = b1 & b2;
System.out.println("b1 & b2: " + b3 + " " + Integer.toBinaryString(b3));
b3 = b1 ^ b2;
System.out.println("b1 ^ b2: " + b3 + " " + Integer.toBinaryString(b3));
b3 = ~b1;
System.out.println("~ b1: " + b3 + " " + Integer.toBinaryString(b3));
b3 = b1 >> 2;
System.out.println("b1 >> 2: " + b3 + " " + Integer.toBinaryString(b3));
b3 = b1 << 2;
System.out.println("b1 << 2: " + b3 + " " + Integer.toBinaryString(b3));
b3 = b1 >>> 2;
System.out.println("b1 >>> 2: " + b3 + " " + Integer.toBinaryString(b3));
}
输出,为了方便查看,进行了对齐,Integer.toBinaryString在输出时会忽略之前的0,在看的时候可以把空白的地方想象成都是0:
b1: -117 11111111111111111111111110001011
b2: 117 1110101
b1 | b2: -1 11111111111111111111111111111111
b1 & b2: 1 1
b1 ^ b2: -2 11111111111111111111111111111110
~ b1: 116 1110100
b1 >> 2: -30 11111111111111111111111111100010
b1 << 2: -468 11111111111111111111111000101100
b1 >>> 2: 1073741794 111111111111111111111111100010
与或非异或运算都很直白。
这里讲一下>>、<<和>>>的区别:
>>
在移位的时候保留符号<<
左移位,在最右边进行补0>>>
在移位的时候不保留符合,而往左边补0
因此>>>
也称作无符号移位。此外只有>>>
而没有<<<
看测试例子:
@Test
public void test2() throws Exception {
Byte b = Byte.parseByte("10101", 2);
System.out.println("b: " + Integer.toBinaryString(b) + " b >> 2: " + Integer.toBinaryString(b >> 2));
System.out.println("b: " + Integer.toBinaryString(b) + " b >>> 2: " + Integer.toBinaryString(b >>> 2));
b = Byte.parseByte("-10101", 2);
System.out.println("b: " + Integer.toBinaryString(b) + " b >> 2: " + Integer.toBinaryString(b >> 2));
System.out.println("b: " + Integer.toBinaryString(b) + " b >>> 2: " + Integer.toBinaryString(b >>> 2));
}
结果:
b: 10101 b >> 2: 101
b: 10101 b >>> 2: 101
b: 11111111111111111111111111101011 b >> 2: 11111111111111111111111111111010
b: 11111111111111111111111111101011 b >>> 2: 111111111111111111111111111010
以下对移位和乘除法的性能进行了验证:
- 验证正确性:
```java
@Test
public void test3() throws Exception {
byte b = 66;
long start = System.currentTimeMillis();
for (int i = 0; i < 1; i ++) {
b >>= 3;
System.out.println(b);
b <<= 3;
System.out.println(b);
}
long end = System.currentTimeMillis();
System.out.println("使用移位:" + (end-start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < 1; i ++) {
b /= 8;
System.out.println(b);
b *= 8;
System.out.println(b);
}
end = System.currentTimeMillis();
System.out.println("使用乘法:" + (end-start) + "ms");
}
可以看到二者输出是一致的
```java
8
64
使用移位:0ms
8
64
使用乘法:0ms
- 性能验证,因为编译器进行了优化,移位运算的性能并没有比直接乘除快:
@Test
public void test3() throws Exception {
byte b = 66;
long start = System.currentTimeMillis();
for (int i = 0; i < 500000; i ++) {
b >>= 3;
// System.out.println(b);
b <<= 3;
// System.out.println(b);
}
long end = System.currentTimeMillis();
System.out.println("使用移位:" + (end-start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < 500000; i ++) {
b /= 8;
// System.out.println(b);
b *= 8;
// System.out.println(b);
}
end = System.currentTimeMillis();
System.out.println("使用乘除法:" + (end-start) + "ms");
}
结果:
使用移位:11ms
使用乘除法:8ms
版权声明
本文章由作者“衡于墨”创作,转载请注明出处,未经允许禁止用于商业用途
发布时间:2019年11月28日 16:28:42
备案号:
闽ICP备19015193号-1
关闭特效
评论区#
还没有评论哦,期待您的评论!
引用发言