位运算
2024年7月4日大约 3 分钟
Java 位运算
- 测试代码
@Test
public void testBitOperation(){
System.out.println("44 二进制:" + Integer.toBinaryString(44));
System.out.println("44 << 1:十进制:" + (44 << 1) + " 二进制:" + Integer.toBinaryString(44 << 1));
System.out.println("44 << 2:十进制:" + (44 << 2) + " 二进制:" + Integer.toBinaryString(44 << 2));
System.out.println("44 << 2:十进制:" + (44 << 3) + " 二进制:" + Integer.toBinaryString(44 << 3));
System.out.println();
System.out.println("44 >> 1:十进制:" + (44 >> 1) + " 二进制:" + Integer.toBinaryString(44 >> 1));
System.out.println("44 >> 2:十进制:" + (44 >> 2) + " 二进制:" + Integer.toBinaryString(44 >> 2));
System.out.println("44 >> 3:十进制:" + (44 >> 3) + " 二进制:" + Integer.toBinaryString(44 >> 3));
System.out.println();
System.out.println("-44 :二进制:" + Integer.toBinaryString(-44));
System.out.println("-44 << 1:十进制:" + (-44 << 1) + " 二进制:" + Integer.toBinaryString(-44 << 1));
System.out.println("-44 << 2:十进制:" + (-44 << 2) + " 二进制:" + Integer.toBinaryString(-44 << 2));
System.out.println("-44 << 3:十进制:" + (-44 << 3) + " 二进制:" + Integer.toBinaryString(-44 << 3));
System.out.println();
System.out.println("-44 >> 1:十进制:" + (-44 >> 1) + " 二进制:" + Integer.toBinaryString(-44 >> 1));
System.out.println("-44 >> 2:十进制:" + (-44 >> 2) + " 二进制:" + Integer.toBinaryString(-44 >> 2));
System.out.println("-44 >> 3:十进制:" + (-44 >> 3) + " 二进制:" + Integer.toBinaryString(-44 >> 3));
System.out.println();
System.out.println("44 >>> 1:十进制:" + (44 >>> 1) + " 二进制:" + Integer.toBinaryString(44 >>> 1));
System.out.println("44 >>> 2:十进制:" + (44 >>> 2) + " 二进制:" + Integer.toBinaryString(44 >>> 2));
System.out.println("44 >>> 3:十进制:" + (44 >>> 3) + " 二进制:" + Integer.toBinaryString(44 >>> 3));
System.out.println();
System.out.println("-44 >>> 1:十进制:" + (-44 >>> 1) + " 二进制:0" + Integer.toBinaryString(-44 >>> 1));
System.out.println("-44 >>> 2:十进制:" + (-44 >>> 2) + " 二进制:00" + Integer.toBinaryString(-44 >>> 2));
System.out.println("-44 >>> 3:十进制:" + (-44 >>> 3) + " 二进制:000" + Integer.toBinaryString(-44 >>> 3));
}
测试结果
44 二进制:101100 44 << 1:十进制:88 二进制:1011000 44 << 2:十进制:176 二进制:10110000 44 << 8:十进制:352 二进制:101100000 44 >> 1:十进制:22 二进制:10110 44 >> 2:十进制:11 二进制:1011 44 >> 3:十进制:5 二进制:101 -44 :二进制:11111111111111111111111111010100 -44 << 1:十进制:-88 二进制:11111111111111111111111110101000 -44 << 2:十进制:-176 二进制:11111111111111111111111101010000 -44 << 3:十进制:-352 二进制:11111111111111111111111010100000 -44 >> 1:十进制:-22 二进制:11111111111111111111111111101010 -44 >> 2:十进制:-11 二进制:11111111111111111111111111110101 -44 >> 3:十进制:-6 二进制:11111111111111111111111111111010 44 >>> 1:十进制:22 二进制:10110 44 >>> 2:十进制:11 二进制:1011 44 >>> 3:十进制:5 二进制:101 -44 >>> 1:十进制:2147483626 二进制:01111111111111111111111111101010 -44 >>> 2:十进制:1073741813 二进制:00111111111111111111111111110101 -44 >>> 3:十进制:536870906 二进制:00011111111111111111111111111010
总结
在java的位运算中
" << " ,有符号左移位,将操作数的二进制整体左移指定位数,低位用 0 补齐
正整数x左移n位后的十进制结果,x = x * 2^n
负整数:在java中,负数存储是以补码形式存储的(补码 = 反码 + 1) ,
44 : 101100
-44 : 11111111111111111111111111010100
所以负整数x左移n位后的十进制结果是:x = (|x| + 2^n)
" >> ",有符号右移位,将操作数的二进制整体右移指定位数,整数高位用0补齐,负数高位用1补齐(保持负数符号不变)。
正整数x右移n位后的十进制结果,x = x / (2^n)
负数的有符号右移基本原理还是和左移相同,不同的是结果的计算,因为这是有符号的右移,一直右移最后的结果就会是-1。归纳起来就是,
如果运算数是偶数,那么它的运算结果就是 x = -(|x| / (2^n)) ,
如果运算数是奇数,那么它的运算结果就是 x = -(|x| / (2^n)) - 1。
">>>",无符号右移位,不管正数还是负数,高位都用0补齐(忽略符号位)
正数的>>>无符号右移位和>>有符号右移位计算结果相同
在负数中,虽然无符号移位后的二进制和有符号移位后的二进制看起来相同的,但结果大相径庭,记住有符号右移位操作,实际上是忽略符号的算术操作,即高位统一补0。
-44 >>> 1:十进制:2147483626 二进制:01111111111111111111111111101010