-------
十进制——>二进制/八进制/十六进制(以十六进制为例)。
需求:将一个int num(后面缩写为:int)转换成十六进制。
思路:
1.十六进制数的元素包括:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F(涵盖了二进制和八进制的元素);
2.定义一个包含十六进制元素的数组;
3.将该整数与上十六进制基数15即,得到该数对应的最低四位二进制作为角标去定义的数组表中查找相对应的元素;再将该整数无符号右移四位,继续参与与运算。
步骤:
1.定义函数toHex,实现进制转换;
2.初始化数组char[ ] chs,使其包含0~F这16个字符元素;
3.定义一个临时数组char[ ] arr,用来存储通过临时变量temp在chs表中查找出的字符元素;
4.初始化指针pos,获取临时数组arr的长度(最大角标+1);
5.通过while循环来将获取的十六进制元素存储在临时数组arr中,且满足从数组的最大角标开始存储,依次递减;
6.通过for循环来打印这个临时数组arr,且从数组中元素第一个不是0的地方开始打印,即所转换数的十六进制。
算法:
public static void toHex(int num)
{
char[ ] chs = {'0','1','2','3',
'4','5','6','7',
'8','9','A','B',
'C','D','E','F'};
//定义一个临时容器,类型为char,长度为8:因为需要存储的是int型的十六进制数,所以最多8个元素。
char[ ] arr = new char[8];
//定义指针指向临时数组最后的角标
int pos = arr.length;
while (num != 0)
{
int temp = num & 15;
//将temp低四位值作为角标在表chs中查找对应的元素然后赋给临时表,且倒着存储。
arr[--pos] = chs[temp];
num = num>>>4;
}
//打印该数组,从第pos个角标开始打印,也就是从数组中元素第一个不是0的地方开始打印。
for (int i = pos; i<arr.length; i++)
System.out.print(arr[i]);
System.out.println();
}
通过这段时间的学习,总结一下实现进制转换所用到的方法:
1> 最初的做法(未接触数组):
缺点:不能确定需要右移的次数,不方便打印。
System.out.println(Integer.toBinaryString(75)); //输出二进制
System.out.println(Integer.toHexString(75)); //输出十六进制
int num = 75;
int n1 = num & 15; //获取num的最低4位,通过&15。
//三元运算判断后会输出对应字符ASCII码的十进制值。现在不能实现输出对应的十六进制字符;
System.out.println(n1 > 9 ? (char)(n1 - 10 + 'A') : n1);
int n2 = num >>> 4 & 15; //对num右移4位,然后通过&15,获取(num>>>4)最低4位。
System.out.println(n2 > 9 ? (char)(n2 - 10 + 'A') : n2);
System.out.println("num的十六进制数是:"+"0x"+n2+(char)(n1 - 10 + 'A'));
2> 通过特殊工具存储打印(接触了函数):
StringBuffer是Java定义的特殊容器,用于存储数据,且可以通过 .append( ) 将值传递进该容器中,最后在通过 .reverse( ) 将该数据反转打印。
public static void toHex(int num)
{
StringBuffer sb = new StringBuffer();
//int共占32位,每四位循环一次,最多循环8次。
for (int i = 0; i<8; i++)
{
//取低四位操作。
int temp = num & 15;
if (num>9)
sb.append((char)(temp-10+'A'));
else
sb.append(temp);
num = num>>>4;//正负数都成立
}
System.out.println(sb.reverse());
}
3> 通过查找表的方式:
开头处的十进制转换十六进制就是通过查找表的方式来实现的,现在我们来将该算法优化,使其功能通用,同时满足十进制转换三种进制的要求。首先需要确定返回值类型,是一个字符型(char),因为 int 型数对应的二进制最大有32位,在临时数组中表示就是32个长度,八进制是11个长度,十六进制是8个长度,那么我们定义临时数组 char [ ] arr = new int[32],这满足三种进制存储要求。其次,相比较三种进制转换,不同的内容是偏移量(offset即位移量:1、3、4)和基数(base:1、7、15),我们只需将这量变量和需要转换的数作为自定义函数的参数列表即可。算法如下图:
//十进制-->二进制
public static void toBin(int num)
{
trans(num, 1, 1);
}
//十进制-->八进制
public static void toBa(int num)
{
trans(num, 7, 3);
}
//十进制-->十六进制
public static void toHex(int num)
{
trans(num, 15, 4);
}
//定义公共函数体trans:base:基数(1、7、F),offset:偏移量(进制转换间的位移量)。
public static void trans(int num,int base, int offset)
{
char[] chs = {'0','1','2','3',
'4','5','6','7',
'8','9','A','B',
'C','D','E','F'};
//定义一个临时容器,类型为char,长度为32:因为需要存储的是int型的二进制数(同时满足八和十六进制的存储)。
char[] arr = new char[32];
//定义指针指向临时数组最后的角标
int pos = arr.length;
while (num!=0)
{
int temp = num & base;
//将temp低四位值作为角标在表chs中查找对应的元素然后赋给临时表,且倒着存储。
arr[--pos] = chs[temp];
num = num >>> offset;
}
//打印该数组,从第pos个角标开始打印,也就是从数组中元素第一个不是0的地方开始打印。
for (int i = pos; i<arr.length; i++)
System.out.print(arr[i]);
System.out.println();
}
总结:通过函数封装功能,我们可以将许多重复性的操作简化,直接调用公共函数即可完成我们所需的结果,简化代码,省去许多不必要的步骤。进制转我们需要掌握它的在计算机中运行的原理,即可进行相应的代码编写,后期将会更简单,直接使用java自定义的工具即可实现。在计算机计算中位元算是最快的。