Interger类中进制转换方法的实现原理-通过查表法完成整数的进制转换

来源:互联网 发布:地平线3pc版 优化差 编辑:程序博客网 时间:2024/05/17 22:16
前两天没事看Interger类的源码,看到里面封装的整数进制转换的方法的实现挺有意思的。
Integer.toBinaryString(15); //转换为2进制Integer.toHexString(15);    //转换为8进制Integer.toOctalString(15);  //转换为16进制

于是研究了一下,也动手模拟写了一遍还是挺有收获的。

简单的总结就是结合了Java中的位运算以及算法“查表法”的使用。


首先,计算机中的数据都是以二进制形式的数据保存的。

而二进制与十进制之间的相互转换的原理通常都比较了解 ,

而所谓的八进制和十六进制,实际就是对二进制的数分别以每三位和每四位提取为一个数。


所以如果我们要将其转换为代码,实际上也就是通过这个原理来完成。

也就是如果要将一个十进制的数转换为二进制,八进制或十六进制的话,

就分别以一个比特位,三个比特位,四个比特位的数进行提取就行。

而十六进制因为涉及到一些用数字无法表达的符号“a-f”,所以就可以通过查表法来转换为对应的字符。

而相对来说,要值得斟酌的,就是按比特位提取数进行转换并保持数据的正确性的实现方法了。


既然涉及到比特位的操作,那么首先想到的就是:肯定要使用到位运算符。

按指定比特位数提取数需要用到的是Java当中按位与运算符,因为位与运算符“&”的特性在于:相与的两个数,只要有一个数为0,那么运算得到的结果就是0.

所以想要将一个数按位取值,并保证值的正确性,就让它和相同位数的“1”进行与运算就搞定了。


举例来说,十进制的数“12”的二进制表现形式为:0000-0000 0000-0000 0000-0000 0000-1100

如果我们要将其转换成八进制来讲,就是每次按三个比特位进行提取。

要做的工作就是让他每次与相同位数的“1”,也就是111进行与运算,那么:

0000-0000 0000-0000 0000-0000 0000-1100 与上

0000-0000 0000-0000 0000-0000 0000-0111

得到的结果就是:

0000-0000 0000-0000 0000-0000 0000-0100

接下来要做的就简单了,当成功取出3位之后,我们要做的自然就是将已经提取出的三位移出,

那么对应的也就是使用Java的移位运算符“>>>”对数进行移位运算了,既然是移除三位,那么也就是">>>3"。


了解了原理之后,要做的也就是对以上所说的步骤进行循环,直至取出所有有效位,完成整个转换工作。


不再废话,看一眼实现代码吧:

/** * 进制转换工具类 * 利用算法:查表法,完成整数的进制转换 * @author Hql * */public class HexadecimalConversion {    public static String toBinaryString(int num) {        return conversion(num, 1, 1);    }    public static String toOctalString(int num) {        return conversion(num, 7, 3);    }    public static String toHexString(int num) {        return conversion(num, 15, 4);    }    /**     * 进制转换运算     * @param num    要进行转换的10进制目标数     * @param base   对应提取位数的数进行与运算的基础数 (2进制为1,8进制为111:7,16进制为1111:15)     * @param offSet  移位运算的偏移量     */    public static String conversion(int num, int base, int offSet) {        String buffer = "";        if (num == 0) {            buffer += "0";            return buffer;        }        // 绘制一张对应关系表        char[] ch = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',                'B', 'C', 'D', 'E', 'F' };        // 定义一个char数组,存放对应的符号        char[] temps = new char[32];        int position = temps.length;        // 当num不等于0        while (num != 0) {            int temp = num & base;            //存放进目标数组            temps[--position] = ch[temp];            //没取出一个数后,将这几位数移出            num = num >>> offSet;        }        for (int i = position; i < temps.length; i++) {            buffer+=temps[i];        }                return buffer;    }    public static void main(String[] args) {        System.out.println(HexadecimalConversion.toBinaryString(12));        System.out.println(HexadecimalConversion.toOctalString(12));        System.out.println(HexadecimalConversion.toHexString(12));                System.out.println(Integer.toBinaryString(12));        System.out.println(Integer.toOctalString(12));        System.out.println(Integer.toHexString(12));    }    }


程序的打印结果:

1100
14
C
1100
14
c


3 0
原创粉丝点击