进制运算
1) ~取反
2) &与
&与计算(逻辑计算)
基本规则:有0则0
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
计算时,需要将两个数字对其位数,对应位置计算与计算
例子:
n = | 01110111 | 01010100 | 10111111 | 01010111 | |
---|---|---|---|---|---|
m = | 00000000 | 00000000 | 00000000 | 11111111 | Mask |
n&m = | 00000000 | 00000000 | 00000000 | 01010111 |
-如上计算的意义:如上是掩码(Mask)计算(拆分计算),其拆分结果 k 是 n 的最后是8位
实验验证:
public class Demo {
public static void main(String[] args) {
int n = 0x7754bff7;
int m = 0xff; //8位掩码(Mask):1的个数有8个
int k = n & m;
//按照2进制验证结果
System.out.println(Integer.toBinaryString(n));
System.out.println(Integer.toBinaryString(m));
System.out.println(Integer.toBinaryString(k));
}
}
3) |或
基本规则:有1则1
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
计算时,将两个数的数位对齐,对应位进行或计算
例子:
n = 00000000 00000000 00000000 10011101
m = 00000000 00000000 11011111 00000000
n&m = 00000000 00000000 11011111 10011101
-如上计算意义:将 n 和 m 两个数字进行拼接计算
验证:
public class Demo {
public static void main(String[] args) {
int n = 0x9d;
int m = 0xdf00;
int k = n | m;
System.out.println(Integer.toBinaryString(n));
System.out.println(Integer.toBinaryString(m));
System.out.println(Integer.toBinaryString(k));
}
}
4) >>右移位 (<<左移位)
<<<左移位
将2进制数字每个位向左移动,高位溢出,低位补0
移位计算的数学意义
回顾10进制小数点移动计算:
// 89191.
// 891910.
// 8919100.
// 10进制时,数字向左移动一次,数值扩展10倍
===========================================================
// 110010. 50
// 1100100. 100 = 50 << 1
// 11001000. 200 = 50 << 2
// 2进制时,数字向左移动一次,数值扩展2倍===========================================================
// 110010. 50
// 11001. 25 = 50 >> 1
// 1100. 12 = 50 >> 2 (多余的省略)向小方向取整
5) >>>逻辑右移位(<<<逻辑左移位)
n = 01110111 01010100 10111111 01010111
n>>>1 = 00111011 10101010 01011111 10101011
n>>>2 = 00011101 11010101 00101111 11010101
n>>>8 = 00000000 01110111 01010100 10111111
实验验证:
public class Demo {
public static void main(String[] args) {
int n = 0x7754bff7;
int m = n>>>1;
int k = n>>>2;
int g = n>>>8;
int b3 = (n>>>8) & 0xff;
System.out.println(Integer.toBinaryString(n));
System.out.println(Integer.toBinaryString(m));
System.out.println(Integer.toBinaryString(k));
System.out.println(Integer.toBinaryString(g));
System.out.println(Integer.toBinaryString(b3));
}
}
b1 = 00000000 00000000 00000000 10111011 0xbb;
b2 = 00000000 00000000 00000000 01101111 0x6f;
b3 = 00000000 00000000 00000000 10111011 0xbb;
b4 = 00000000 00000000 00000000 01110111 0x77;
b1<<<24 = 10111011 00000000 00000000 00000000 0xbb;
b2<<<16 = 00000000 01101111 00000000 00000000 0x6f;
b3<<<8 = 00000000 00000000 10111011 00000000 0xbb;
b4 = 00000000 00000000 00000000 01110111
n = (b1 <<< 24) | (b2 <<< 16) | (b3 <<< 8) | b4
n = 10111011 01101111 10111011 01110111
>> 和 >>> 的区别
'>>'称为数学右移位计算,当正数时候(高位为0),高位补0,当负数时(高位为1)高位补1,其运算结果是数学除法,向小方向取整
‘>>>’称为逻辑右移位计算,无论正负高位都补0,负数时候不符合数学运算结果
例子:
n = 11111111 11111111 11111111 11001110 -50
m = n >> 1 11111111 11111111 11111111 11100111 -25
g = n >> 2 11111111 11111111 11111111 11110011 -13
k = n >>> 1 01111111 11111111 11111111 11100111 比最大值小24
‘>>’ 运算是最接近数学结果的:除以2向小方向取整
‘>>>’ 单纯将数位向右移动,其结果不考虑数学意义,进行数字拆分合并时,采用纯正的右移动
面试案例:替代2的整数倍乘法,使用采用数学移位!
n * 32 可以替换为 (n << 5)
n / 2 可以替换为 (n >> 1)