---------------------- ASP.Net+Unity开发、 .Net培训、期待与您交流! ----------------------
本文将用程序代码分析如何将十进制转换为二进制,八进制,十六进制。
首先,分析一下进制转换的方法。
一、十进制转换为二进制:
转换方法:十进制整数转换为二进制整数采用"除2取余,逆序排列"法。具体做法是:用2整除十进制整数,可以得到一个商和余数;再用2去除商,又会得到一个商和余数,如此进行,直到商为0时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。
举例:给定十进制数“173”,转换为二进制数
图解:
程序实现:
public static String toBinary(int num){
StringBuffer sb = new StringBuffer();
while(num > 0){
sb.append(num%2);
num = num/2;
}
return sb.reverse().toString();
}
二、十进制转换为八进制
转换方法:与二进制类似,只是八进制的基数为8,除8取余。把上图中的2换成8,可计算得出173的八进制值为“255”。
程序实现:
public static String toBa(int num){
StringBuffer sb = new StringBuffer();
while(num > 0){
sb.append(num%8);
num = num/8;
}
return sb.reverse().toString();
}
三、十进制转换为十六进制
转换方法:同上。只是十六进制有一个特殊,十六进制数总共有:0~15,逢十六进1。但是大于9的数,不能用数字表示,要用字母表示。10~15对应的是A、B、C、D、E、F。所以在使用十进制数除16时,如果余数大于9,那么就转换成字母。该转换方法为:(余数-10 + 'A')。
程序实现:我们分析得知,整型数据(int)是32位的。每一位十六进制数用4个二进制位表示,所以十进制转换为十六进制只需转换八次。num%16等价于num&15,num/16等价于num>>>4(右移四位),如下面的程序。
public static String toHex(int num){
StringBuffer sb = new StringBuffer(); //定义一个StringBuffer对象作为存储区域。
for(int i=0;i<8;i++){
int temp = num & 15; //定义一个中间变量temp,就收(num&15)的结果。(num & 15)等价于num%16
if(temp > 9){
//如果(num&15)的结果大于9,则需要转换为字母形式表示
sb.append((char)(temp-10 + 'A'));
}else{
sb.append(temp);
}
num = num >>> 4; //无符号右移四位
}
sb = sb.reverse(); //字符串反转操作
/*
while循环去掉前面的0,例如:十进制的100,
转换成十六进制为“00000064”,经过这个while循环处理得到“64”。
从左到右去零,直到碰到一个非0.
*/
while(sb.length() > 0){
if(sb.substring(0, 1).equals("0")){
sb.deleteCharAt(0);
}else{
break;
}
}
return sb.toString();
}
通过分析,我们发现,与十六进制的转换类似,十进制转换为二进制时,(num%2)等价于(num&1),(num/2)等价于(num>>>1)。十进制转换八进制时,(num%8)等价于(num&7),(num/8)等价于(num>>>3)。所以,等到如下程序:
转二进制:
public static String toBinary2(int num){
StringBuffer sb = new StringBuffer();
while(num > 0){
sb.append(num&1);
num = num>>>1;
}
return sb.reverse().toString();
}
转八进制:
public static String toBa2(int num){
StringBuffer sb = new StringBuffer();
while(num > 0){
sb.append(num&7);
num = num>>>3;
}
return sb.reverse().toString();
}
我们发现上面程序中得出的结果都是反向的,必须使用StringBuffer的reverse方法进行转换。下面来进行优化一下。
上面程序中,我们直接使用了StringBuffer作为存储容器,下面我们使用另外一个容器——数组,来存储数据。要保证出来的结果不是反向的,我们要将指针定位在数组的末尾,逐一往前存储。使用查表法将上面的程序优化如下:
/**
* 使用查表法实现十进制转换成二进制,八进制,十六进制的操作。
* @author anjadeluo
*
*/
public class DecimalConversion3 {
/**
* 进制转换对照表:该表用于进制转换时,对相应的数进行查找。
* 该对照表中,包含了二进制数(0,1),八进制数(0~7),十六进制(0~9,A~F),并且每个数都对应着相应的下标。
* 数组的下标其实就是等于num&基数(二进制-1;八进制-7;十六进制-15)的值。
*/
public static char[] chs = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
/**
* 进制转换。输入一个整数和转换方式,转换不同的进制
* @param num:待转换的数
* @param symbol:转换方式(二进制-2,八进制-8,十六进制-16)
* @return (返回对应进制数的字符串)
*/
public static String toXxx(int num ,int symbol){
switch(symbol){
case 2:
return trans(num,1,1);
case 8:
return trans(num,7,3);
case 16:
return trans(num,15,4);
default:
return "暂无该进制";
}
}
/**
* 进制转换的共通函数
* @param num:待转换的十进制数
* @param base:基数(二进制-1;八进制-7;十六进制-15)
* @param offset:偏移量(二进制-1;八进制-3;十六进制-4)
*/
public static String trans(int num ,int base ,int offset){
StringBuffer sb = new StringBuffer();
if(num == 0){
sb.append(num); //如果输入的整数是0,则返回0,直接结束。因为所有进制的0,都是0.
return sb.toString();
}
char[] arr = new char[32]; //定义一个数组
int pos = arr.length; //定义一个指针变量,用于指示进制数存放在数组中的位置,为了保证出来的结果非反向的,我们需要从数组末尾开始存储,所以指针定位在数组末尾。
while(num != 0){
int temp = num & base; //待转换的整数与基数进行与运算。
arr[--pos] = chs[temp]; //使用(num & base)的结果查表,得出的结果存放在数组中pos的位置。
num = num >>> offset; //待转换的整数无符号右移“偏移量”位
}
while(pos < arr.length){
sb.append(arr[pos++]); //遍历数组,将有效数据存放到StringBuffer中。
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(toXxx(173,2));
System.out.println(toXxx(173,8));
System.out.println(toXxx(173,16));
}
}
详细请查看:http://edu.csdn.net