将十进制数转换成二进制形式(比较复杂)

下面用递归方式来实现将十进制数转换成二进制形式的字符串,在编写这个程序之前,必须先了解熟知的进制表示原理,同样一个数值,可以用多种进制进行表示,就好比同样的钱,可以用多种度量单位。所谓要讲一个十进制数转换成二进制数形式,启示,就是计算出该数值的二进制形式,只是我们通常习惯用十进制表示一个数值,所以,一个二进制数值也可以理解成是有某个十进制数转换成的。为了便于理解一个数值的二进制表示原理,我们先看看讲一个数值转换成十进制字符串的过程。例如,要得到数值825中按十进制表示的每一位,就是先用这个数除以10,得到的余数为个位,用得到的商再去除以10,得到的余数就是十位,依次递推,就可以得到这个数中的每一位,最先得到的是低位,最后得到的是高位。同样的道理,要将一个数值表示成二进制形式,可以用这个数除以2,得到的余数就是二进制数的最低位,然后在用商去除以2,得到的余数就是二进制数的次低位,然后再用这次运算的商除以2,得到的余数为二进制数的第三个低位,依次递推,直到商为0时,得到的所有余数按照出现顺序的倒序排列的结果就是转换成的二进制数。例如,求十进制数10的二进制形式的过程如下:

被除数 除数 余数

10 2 0

商 5 2 1

商 2 2 0

商 1 2 1

商 0

通过上表得出的余数按照从后到先的顺序依次排列,结果为:1010,那么,1010就是十进制数10的二进制表示。

可见,一个十进制数所对应的二进制数,就是在这个十进制数除以2的商所对应的二进制数的基础之上,再在其尾部追加这个十进制数除以2的余数,所以,这个问题采用递归的方式进行处理,下一次递归调用的问题域就是当前要转换的十进制数除以2的商。

假设要编写的这个将十进制数转换成二进制数递归方法的名称为toBin,这个方法接受两个参数,一个是要进行转换的十进制数,另一个是一个StringBuilder对象,用做收集转换结果的容器。在toBin方法内部要将除以2的商作为下一次递归调用的参数值再次调用的参数值再次调用toBin方法,如果参数值为0时,则结果递归调用。在toBin方法每次调用时,都要将每次当前参数除以2的余数依此追加到StringBuilder容器对象中,最后从StringBuilder对象中获得的结果就是转换后的二进制数。

将一个十进制数转换成二进制数的参考程序代码历程如下所示:

public class
Bin
{
public static void main(String[] args)
{
StringBuffer sbf = new StringBuffer();
toBin(19,sbf);
System.out.println(sbf);
}
static void toBin(int x,StringBuffer
result)
{
result.append(x%2);
toBin(x/2,result);
}
}

注意,执行结果是11001,与真实结果相反,把System.out.println(sbf)改为System.out.println(sbf.reverse()),结果变为10011,是真确的了,其中reverse()方法是起到逆序作用。、

另外,张孝祥老师给出另一种方法,比较有技巧性,他把

toBin方法中的两句(把toBin(x/2,result)放在result.append(x%2)前边,)

的顺序交换,这样System.out.println(sbf)打印出来就正确了。为啥呢?

为了便于大家更好的明白上面的倒序输出的效果,大家可以借着如下问题想一想,假设在第一次toBin(x)方法中,在调用子方法toBin(x/2)之前,和之后打印x%2的值,请问本次打印的值一样吗?是一样的,知识前者输出的值是toBin(x/2)方法内部的打印语句之前打印,后者输出的值在toBin(x/2)方法内部的打印语句之后打印。