标签:
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
在java中数字的表现形式一般有二进制,八进制,十进制,十六进制等,在平时的编程中我们可以通过java提供的API函数方便的实现各个进制间的转换,如:Integer.toHexString(int i)--十进制转十六进制;Integer.toOctalString(int i)十进制转八进制;Integer.toBinaryString(int i)十进制转二进制等。通过API函数实现的方式非常的简单便捷,如果我们学习的过程中能了解这些函数实现的原理,能够了解进制转换的实现方式,对于我们加深对于java语言的理解,提升利用编程语言解决实际问题的能力有很大的帮助。在这一篇博文中我将简单的介绍各个进制直接转换的原理,以及实现方式,进一步介绍查表法实现进制转换的方法,并且提取进制转换的公共函数。
一、直接转换
1、十进制转二进制
十进制转换为二进制时,先将十进制数对2取余,再将十进制数除以2,如此循环直到十进制数变为1,余数的倒序就是十进制数的二进制表示方法,具体如下图所示:
具体的代码为:
1 /** 2 * 直接转换,十进制到二进制 3 * @param number 4 */ 5 public static void toBin(int number) 6 { 7 StringBuffer sb =new StringBuffer(); 8 while(number>0) 9 { 10 sb.append(number%2); //对2取余 11 number=number/2; //除以2 12 } 13 System.out.println(sb.reverse()); 14 }
2、十进制转八进制
十进制转八进制与转二进制的情况类似,只是取余的数和除以的除数都由2变为了8
所以具体的代码为:
1 /** 2 * 直接转换,十进制到八进制 3 * @param number 4 */ 5 public static void toOctal(int number) 6 { 7 StringBuffer sb =new StringBuffer(); 8 while(number>0) 9 { 10 sb.append(number%8); //与二进制不同这里是8 11 number=number/8; //与二进制不同这里是8 12 } 13 System.out.println(sb.reverse()); 14 }
3、十进制转十六进制
十进制转十六进制与前面的二进制、八进制不同的地方就是十六进制有字母ABCDEF,取余的数如果大于9需要进行一下转换,10-A,11-B,12-C,13-D,14-E,15-F
如果余数是temp那么统一的转换公式是temp-10+‘A‘,这个表达式可能不是很好理解,这里其实看明白了其实很容易理解,把字符’A‘看作是A的ascII码值,temp比10大几就用A的码值加几最终得到相应字符的码值。
详细的代码为:
1 /** 2 * 直接转换,十进制到十六进制 3 * @param number 4 */ 5 public static void toHex(int number) 6 { 7 StringBuffer sb = new StringBuffer(); 8 while(number>0) 9 { 10 int temp =number%16; 11 if(temp>9) 12 sb.append((char)(temp-10+‘A‘)); 13 else 14 sb.append(number%16); 15 16 number=number/16; 17 } 18 System.out.println(sb.reverse()); 19 }
上面的三种转换方式都用到了StringBuffer类的反转函数来实现倒序,仔细观察发现这三个函数有很多相同的地方,那么就可以考虑提取公共的函数来优化程序,函数不一样的地方只有取余和除数,通过函数的参数来取消不一致的地方就可以提取出来一个公共的函数了。
详细的代码为:
1 /** 2 * 十进制转其他进制 3 * @param number 要转的数 4 * @param key 进制数 5 */ 6 public static void toAny(int number,int key) 7 { 8 StringBuffer sb = new StringBuffer(); 9 while(number>0) 10 { 11 int temp =number%key; 12 if(temp>9) 13 sb.append((char)(temp-10+‘A‘)); 14 else 15 sb.append(number%key); 16 17 number=number/key; 18 } 19 System.out.println("toAny-"+key+":"+sb.reverse()); 20 }
主函数及测试结果:
1 /**主函数 2 * @param args 3 */ 4 public static void main(String[] args) { 5 // TODO Auto-generated method stub 6 toBin(60); 7 toAny(60,2); 8 9 toOctal(60); 10 toAny(60,8); 11 12 toHex(60); 13 toAny(60,16); 14 } 15 16 17 //测试结果 18 toBin:111100 19 toAny-2:111100 20 toOctal:74 21 toAny-8:74 22 toHex:3C 23 toAny-16:3C
结果证明toAny函数和单个函数执行的结果一直,提取的公共函数是可行的。
二、查表法
上面介绍的toAny函数能比较好的处理十进制到其他进制的转换,但是还是存在致命的缺陷,无法处理负数的转换,而查表法就能很好的避免这个缺陷,同时实现起来更加简单。
查表法的思路是:
根据前面的经验,我们可以发现通过查表法转二进制、八进制、十六进制也可以通过同一个公共函数来处理,各个进制不同的部分可以通过参数来处理。
查表法的代码为:
1 /** 2 * 查表法进行进制转换 3 * @param number 要转换的数值 4 * @param key 对应的进制数,2-二进制,8-八进制,16-十六进制 5 */ 6 public static void searchTable(int number,int key) 7 { 8 if(number==0) 9 return; 10 int base,offset;// base 转换的基数,二进制-1,八进制-7,十六进制-15 11 // offset 偏移的数值,二进制-1,八进制-3,十六进制-4 12 switch(key) 13 { 14 case 2: 15 base =1; 16 offset =1; 17 break; 18 case 8: 19 base =7; 20 offset=3; 21 break; 22 case 16: 23 base =15; 24 offset =4; 25 default: 26 base=1; 27 offset=1; 28 break; 29 } 30 char[] chs = {‘0‘,‘1‘,‘2‘,‘3‘, 31 ‘4‘,‘5‘,‘6‘,‘7‘, 32 ‘8‘,‘9‘,‘A‘,‘B‘, 33 ‘C‘,‘D‘,‘E‘,‘F‘}; 34 char[] arr =new char[32]; 35 int pos=arr.length; 36 while(number!=0) 37 { 38 int temp=number & base; 39 arr[--pos]=chs[temp];//脚标由大到小存储,存的时候就是倒序的,取得时候直接输出就是答案 40 number=number>>>offset; 41 42 } 43 for(int i=pos;i<arr.length;i++)//有几个不为0的值就打印几个 44 { 45 System.out.print(arr[i]); 46 } 47 48 }
主函数和对应的测试结果:
1 /** 2 * 主函数 3 * @param args 4 */ 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 //查表法十进制转二进制 8 System.out.println("\n60的二进制:"); 9 searchTable(60,2); 10 //查表法十进制转八进制 11 System.out.println("\n60的八进制:"); 12 searchTable(60,8); 13 //查表法十进制转十六进制 14 System.out.println("\n60的十六进制:"); 15 searchTable(60,16); 16 }
测试结果为:
60的二进制:
111100
60的八进制:
74
60的十六进制:
111100
至此,进制转换的总结就完了,方便自己回顾和复习。
标签:
原文地址:http://www.cnblogs.com/dengzhenyu/p/4782480.html