进制转换
任意进制转换为二进制
常见的进制转换问题都是在二进制,四进制,八进制,十进制,十六进制之间转换,因此为了提高程序的复用性我选择将二进制作为中间量,所有转换都经过二进制进行变换。
转换流程
解析字符串
在进行进制转换之前,我们需要把输入的字符串转换成整数类型
Java可以利用java.lang 中 Integer 对象的 parseInt 方法将字符串直接转化成我们想要的整数类型。当然我们也可以自己写一个 parseInt 方法,只需要将字符编码转换成整数编码即可,十六进制需要特殊处理一下。不过 Java 有自带的解析字符串方法还是最好用自带的方法,因为 Java 自带的方法具有十分成熟的异常处理机制,如下图。
Integer 官方文档
这里第一个参数String s为你需要输入的字符串,int radix 为该字符串的进制。
Java 自带的字符串解析函数自带了4个异常处理机制,分别为:
- 字符串为空异常
- 进制数输入异常
- 输出的进制数不是指定字符串的进制的异常
- 非整数值异常
如过我们要要解析一个浮点数那么可以将字符串以小数点分割一下,可以使用 String 类中的 spit 方法:
split 的参数是一个正则表达式,split 方法会匹配输入的正则式并以其分开,最后返回分开的字符串数组。
正则表达式是由普通字符(例如字符 a 到
z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
如过是一个负数可以先直接取相反数变成正数运算最后结果取反就可以
转换
我们都知道所有数在计算机都是以二进制储存的,Java中 int 占 4 字节也就是 32 位,所以在计算机中就应该是一个长度为 32 的数组。
先上图:
上图是整数10在计算机中的储存形式,前 28 位都是 0 最后 4 位加权一下正好为 10。看到这里,应该会产生一个想法,所有数在计算机都是二进制存储,那么一个数转换成二进制就直接把二进制拿出来不就行了么。的确我们可以拿出来不过需要一些手段,因为我们无法直接得到二进制数,计算机每次都会把二进制数转换完才拿给我们。
既然我们无法直接打到二进制位,那我们能不能一位一位的拿呢,答案是可以的。我们需要以下的一些运算。
- & 逻辑与运算
- >>> 移位运算符
说一说两个运算符的作用:
- 首先逻辑与是将两个数做与运算当然是二进制的与运算,如 1 & 0 = 0 ,1 & 1 = 1,0 & 0 = 0 。
- 其次 >>> 运算符也是二进制的运算可以将所有二进制位向右平移一个单位请参照下图:
其实右移一位和把该数除以2是一个作用,可以算一算,上面是10下面是5.原理很简单,10其实是 2 3 + 2 1 2^3+2^1 23+21 右移一位变成 2 3 − 1 + 2 1 − 1 2^{3-1} + 2^{1-1} 23−1+21−1 但是要用移位运算不要用除法运算因为移位运算的指令周期要比乘除法的指令周期小很多。
明白了移位运算和逻辑与运算,那么接下来在引入一个数字 1 就可以解决进制转换的问题了。
提示:
- 1 与任何数做逻辑与运算会返回这个数的二进制数最后一位的一个整数类型的值如 1 & 10 = 0 , 1 & 3 = 1
下图展示了利用移位运算把目标数的二进制数每一位都和 1 做逻辑运算:
有了上面的性质我们就可以利用移位指令把一个数的二进制数保存在一个数组里了。
具体实现由一个简单的代码构成:
package com.convert;
public class ConvertSystem {
// target为parseInt转换后的整数
public int[] ConverToBinary(int target) {
int len = 32; // 整数一般为4字节也就是32位
int[] nums = new int[len];
for(int i=len-1;i>=0;i--) {
nums[i] = target & 1;
target >>>= 1; // 移位并赋值
}
return nums;
}
}
我们来测试一下
package com.convert; // 和上面的在一个包下
public class Test {
String num = "10"; // 待测试的字符串
int target = Integer.parseInt(num,10); // 解析为整数
public static void main(String[] args) {
ConvertSystem cs = new ConvertSystem();
Test ts = new Test();
int[] a = cs.ConverToBinary(ts.target); // 调用上面的函数
for(int i=0;i<32;i++) { // 输出二进制数
System.out.print(a[i]+" ");
}
}
}
运行结果:
二进制到其他进制
到了这里就非常简单了
十进制最简单先说:
转换为十进制只要把每一位乘以
2
n
−
1
2^{n-1}
2n−1 即可,如 1010 到十进制就是
0
×
2
0
+
1
×
2
1
+
0
×
2
2
+
1
×
2
3
=
10
0×2^0+1×2^1+0×2^2+1×2^3 = 10
0×20+1×21+0×22+1×23=10
介绍一下十六进制:
一个十六进制数由 4 个二进制构成所以没 4 个二进制数决定一个十六进制数
用一个简单的图:
每四个一组决定 16 进制的一个数,是不是很直观清晰,那笔者就不在赘述了,
转换成其他的进制如 4 进制 8 进制都可以参考 16 进制的例子。