本文起源于易样学习hashmap原理时看到hashmap扩容机制发现自己对二进制运算忘得差不多了,可能大部分人和我差不多,平常工作中用不到的技术,你学习了是不错,但是忘记的会很快,这就需要我们经常性的复习我们学习过的技术(这里手动狗头棒砸向自己)
1、十进制转二进制
将十进制数除以2直至商为0或者1,将每一步的余数记录下来,然后将余数反过来就是相应的二进制了
例子:十进制8转二进制
第一次8除以2得4余0,第二次4除以2得2余0,第三次2除以2得1余0,最后余1,得到的余数依次为0001。
反过来就是1000,计算机内部表示数的长度是固定的,比如8位,16位,32位,位数不足在高位补齐(为什么在高位,因为在高位补0对这个数没影响)
Java代码实现:
public class mapHashCodeTest {
public static void main(String[] args) {
String str = toBinary(8);
System.out.println(str);
}
static String toBinary(int num) {
String str = "";
while (num != 0) {
str = num % 2 + str;
num = num / 2;
}
return str;
}
}
2、二进制转十进制
二进制1000 ,转十进制的话,只要拿对应位上的0、1数字乘以2的幂(这里的幂次从个位开始算,个位是零,依次往后推)
8 = 0 * 2(0次幂) + 0 * 2(1次幂) + 0 * 2(2次幂) + 0 * 2(3次幂)
可以直接调用Integer.parseInt()实现,例如:
System.out.println(Integer.parseInt("1000",2));
结果为:8
3、位与运算(&)
如果是二进制数则可以直接进行运算,如果是十进制或者十六进制则需要转换为二进制进行运算。运算规则为:从个位开始,两个数都为1则为1,否则为0
例如:
8的二进制为1000, 9的二进制为1001,位与运算后为1000
代码实现:
int a = 8;
int b = 9;
System.out.println(a&b); // 结果为8
与运算在很多场景中都会用到,例如ip地址和子网掩码进行与运算得到网络地址。
4、位或运算(|)
两个数都转为二进制数,运算规则:从个位数开始,两个数只要有一个为1则为1,否则为0。
例如:
8的二进制为1000, 9的二进制为1001,位或运算后为1001
代码实现:
int a = 8;
int b = 9;
System.out.println(a|b); // 结果为9
5、位异或运算(^)
运算规则是:两个数转为二进制,然后从高位开始比较,如果相同则为0,不相同则为1。
例如:
8的二进制为1000, 9的二进制为1001,位异或运算后为0001
代码实现:
int a = 8;
int b = 9;
System.out.println(a^b); // 结果为1
接下来比较绕,请仔细看
6、位非运算符(~)
将数转为二进制数,运算规则:从个位数开始,位为1则为0,位为0则为1。
Java中所有数据的表示方法都是以补码的形式表示,如果没有特别说明,Java中的数据类型默认是int, int数据类型的长度是8位,一位是4字节,就是32字节,32bit。
例如:
8的二进制为1000,
补码后为:0000 0000 0000 0000 0000 0000 0000 1000
取反为:1111 1111 1111 1111 1111 1111 1111 0111
因为高位是1,所以原码为负数,负数的补码是其绝对值的原码取反,末尾再加1
因此我们可将这个二进制数的补码进行还原,
末尾减1得反码:1111 1111 1111 1111 1111 1111 1111 0110
将反码取反得原码:0000 0000 0000 0000 0000 0000 0000 1001
去除补码位得1001,所以8位非得到-9
代码实现:
int a = 8;
System.out.println(~a); //结果为-9
如果你喜欢本文,
请扫描二维码关注获取更多文章