我们知道,在计算机的世界里,只能识别0和1,也就是二进制,鉴于此阅读性较差的特点,在开发过程中使用的频率较低。除了二进制,还有八进制、十进制、十六进制,其中十进制是我们通常使用的进制。
我们来看看四大进制各自到的表达数据的方式:
1)二级制:由0和1数字组成,逢2进1,前置开头0B或0b,不区分大小写,例如0b1010,表示十进制的10。
2)八进制:每3个二进制位组成一个八进制位,由0~7的数字组成,逢8进1,前置开头0,例如012,表示十进制的10。
3)十进制:由0~9的数字组成,逢10进1。
4)十六进制:每4个二进制位组成一个十六进制位,由09的数字以及A(对应10)F(对应15)的字母组成,逢16进1,前置开头0X或0x,不区分大小写,例如0xA,表示十进制的10。
进制 | 前缀 | 举例 |
---|---|---|
二进制 | 0B或0b | 0b1010 |
八进制 | 0 | 012 |
十进制 | 默认无前缀 | 10 |
十六进制 | 0x或0X | 0xA |
从上面可以看到十进制的10可以用0b1010(二进制)、012(八进制)、0xA(十六进制),此时各位小伙伴肯定在思考,它们之间是怎么进行转换的呢?这就涉及到各个进制之间的转换规则了。
我们还是以我们熟悉的十进制为例,来举例说明十进制与其他进制之间的转换。
1)其他进制与十进制之间的转换
我们先来看看二级制数与十进制数之间的互相转换,二进制数0b1010等同于十进制数的10。
仔细观察,可以看出转换规则:
其他进制转十进制:
其实是可以套公式的。a*m^(n-1),a为每一位对应的数字,m为进制数,n为每一位对应的序号。
十进制转其他进制:
用十进制数不断除以m进制数,直到商为0,然后将每步得到的余数倒过来得到的就是对应的m进制数。
2)其他进制之间的转换
1、二进制数与八进制数互相转换
我们知道一个八进制位由3个二进制位组成,那么在二进制数转八进制数的时候,就需要将二进制数从右往左每3位一组,转换成八进制数即可。
相反的,八进制数转二进制数时,只需要将上述流程翻转即可,将一个八进制位转换为3个二进制位。
2、二进制数与十六进制数互相转换
我们知道一个十六进制位由4个二进制位组成,因此,在二进制数转换为十六进制数的时候,就需要将二进制数从右往左每4位一组,转换成十六进制数即可。
相反的,十六进制数转二进制数的时候,只需要将上述流程翻转即可,将一个十六进制位转换为4个二进制位。
3、常用API
进制转换 | API |
---|---|
十进制转二进制 | Integer.toBinaryString(int i) |
十进制转八进制 | Integer.toOctalString(int i) |
十进制转十六进制 | Integer.toHexString(int i) |
十进制转任意进制 | Integer.toString(int i, int radix) |
代码示例:
public class TestBase {
public static void main(String[] args) {
int num = 1024;
System.out.println(Integer.toBinaryString(num));
System.out.println(Integer.toOctalString(num));
System.out.println(Integer.toHexString(num));
System.out.println(Integer.toString(num,2));
System.out.println(Integer.toString(num,8));
System.out.println(Integer.toString(num,16));
}
}
输出结果:
位运算符是用来对二进制位进行操作的,包括"与(&)"、“或(|)”、“异或(^)”、“非(~)”、“左位移(<<)”、“右位移(>>)”、“无符号右移(>>>)”
两个操作数的对应位都为1时,该位的结果1,其余情况都为0。
操作数 | 数值 | 数值 | 数值 | 数值 |
---|---|---|---|---|
操作数1 | 0 | 0 | 1 | 1 |
操作数2 | 0 | 1 | 0 | 1 |
与(&)运算结果 | 0 | 0 | 0 | 1 |
代码示例:
/**
* a&b的结果是: 8
* a的二进制数: 1010
* b的二进制数: 1100
* a&b的二进制数:1000
*/
public static void main(String[] args) {
int a = 10;
int b = 12;
System.out.println("a&b的结果是:" + (a & b));
System.out.println(Integer.toBinaryString(a));
System.out.println(Integer.toBinaryString(b));
System.out.println(Integer.toBinaryString(a & b));
}
两个操作数的对应位只要其中一个为1,该位的结果为1,其余情况都为0。
操作数 | 数值 | 数值 | 数值 | 数值 |
---|---|---|---|---|
操作数1 | 0 | 0 | 1 | 1 |
操作数2 | 0 | 1 | 0 | 1 |
或(|)运算结果 | 0 | 1 | 1 | 1 |
/**
* a&b的结果是: 14
* a的二进制数: 1010
* b的二进制数: 1100
* a|b的二进制数:1110
*/
public static void main(String[] args) {
int a = 10;
int b = 12;
System.out.println("a|b的结果是:" + (a | b));
System.out.println(Integer.toBinaryString(a));
System.out.println(Integer.toBinaryString(b));
System.out.println(Integer.toBinaryString(a | b));
}
两个操作数的对应位如果不同,该位的结果为1,其余情况都为0。
操作数 | 数值 | 数值 | 数值 | 数值 |
---|---|---|---|---|
操作数1 | 0 | 0 | 1 | 1 |
操作数2 | 0 | 1 | 0 | 1 |
异或(^)运算结果 | 0 | 1 | 1 | 0 |
代码示例:
/**
* a&b的结果是: 6
* a的二进制数: 1010
* b的二进制数: 1100
* a|b的二进制数:0110
*/
public static void main(String[] args) {
int a = 10;
int b = 12;
System.out.println("a^b的结果是:" + (a ^ b));
System.out.println(Integer.toBinaryString(a));
System.out.println(Integer.toBinaryString(b));
System.out.println(Integer.toBinaryString(a ^ b));
}
将操作数位的值取反,0转换为1,1转换为0。
正数的二进制数的第一位为0,负数的二进制数的第一位为1。
6<<2
的结果为24
。
0000 0000 0000 0000 0000 0000 0000 0110 6的二进制数
0000 0000 0000 0000 0000 0000 0001 1000 24的二进制数
-6<<2
的结果为-24
。
1111 1111 1111 1111 1111 1111 1111 1010 -6的二进制数
1111 1111 1111 1111 1111 1111 1110 1000 -24的二进制数
在左位移时,高位舍弃,低位用0补位。
在数字没有溢出范围的前提下,左移1位,相当于乘以2的1次方,左移n位,相当于乘以2的n次方。
正数的二进制数的第一位为0,负数的二进制数的第一位为1。
6>>2
的结果为1
。
0000 0000 0000 0000 0000 0000 0000 0110 6的二进制数
0000 0000 0000 0000 0000 0000 0000 0001 1的二进制数
-6>>2
的结果为-2
。
1111 1111 1111 1111 1111 1111 1111 1010 -6的二进制数
1111 1111 1111 1111 1111 1111 1111 1110 -2的二进制数
在右位移时,低位舍弃,正数高位补0,负数高位补1。
在数字没有溢出范围的前提下,右移1位,相当于除以2的1次方,左移n位,相当于除以2的n次方,结果取商接近的最小整数。
正数的二进制数的第一位为0,负数的二进制数的第一位为1。
6>>>2
的结果为1
。
0000 0000 0000 0000 0000 0000 0000 0110 6的二进制数
0000 0000 0000 0000 0000 0000 0000 0001 1的二进制数
-6>>>2
的结果为1073741822
。
1111 1111 1111 1111 1111 1111 1111 1010 -6的二进制数
0011 1111 1111 1111 1111 1111 1111 1110 1073741822的二进制数
在无符号右位移时,低位舍弃,高位补0。