深入探讨进制转换问题

深入探讨进制转换问题

1.十进制的拆分

​ 对于一个十进制的数字:4572,我们实际上可以将其拆分成:4000+500+70+2。十进制是逢十进一,因此我们可以知道2是2个1,0个10;70是7个10;500是50个10;4000是400个10,我们更进一步的讲,最前边的首位,是其高位上的个位,而后边的零,则代表了数量级,因此4000的数量级是1000,它是一个千位级别的4,而500则是百位级别的5,以此类推。

​ 当然上边的思路并不值得理解,因为这是我自己的脑回路,大家可以按照自己的方式去理解,但总之上我们可以将4572这个数字划分为:**4 * 10^3 + 5 * 10^2 + 7 * 10^1 + 2 * 10^0 **。仔细观察,这不是和二进制转化为十进制的公式非常像吗,接下来我们对二进制进行拆分。

2.二进制的拆分

​ 对于一个二进制的数字:**10101011 **,可以拆分成:10000000 + 0 + 100000 + 1000 + 0 + 10 + 1,在二进制中,是逢二进一,因此我们知道1是代表0个2,1个1;10代表是1个2;1000代表2个2个2;100000代表2个2个2个2个2,为2的五次方;10000000则是2的8次方,其结果即为:1 * 2^0 + 1 * 2^1 + 1 * 2^3 + 1 * 2^5 + 1 * 2^8,这实际上是和我们所记的公式是完全一样的,那个公式的原理就是这样。

3.m进制的拆分

​ 通过上面的推导,我们可以归纳出m进制数字的一个特性,那就是任何一个m进制数字,都可以被拆分成每个数位后边跟着几个0并相加的样式,如16进制ADC103:A00000 + D0000 + C000 + 100 +3。需要注意的是:**拆分时只有这个位数上边是一个非零的数字,它才有意义,否则它的高个位是0,或者说首位是0,它在计算时要乘一个首位0,最终结果就是0,没有意义,所以某个数位上是0可以直接忽略。**实际上这是因为这个位数上没有数位,它的所有位数都进到下一位了。不过我们只需记这个方法就可以了。

4.m进制转化为10进制

​ 通过上面的铺垫,可能大家已经知道了,m进制转化为十进制的方法就是进行拆分后,每个有意义的位乘以m的位数次方并相加,位数就是其后边的0的个数。如m进制数:53267,将它转化为十进制的方式如下。

53267(m进制)
50000 + 3000 + 200 + 60 + 7
5 * m^4 + 3 * m^3 + 2 * m^2 + 6 * m^1 + 7 * m^0
5.十进制转化为m进制

​ 十进制转化为m进制的方式为在之前已经说过了,那就是直接做除法然后统计余数,将余数以从下到上的顺序进行从左到右的排列即可。

6.m进制和n进制之间的转化

​ 人类使用的最舒服的进制实际上就是10进制了,因此m进制和n进制之间的转化,使用10进制当媒介是最舒服最简单也是最好理解的,在进制转换时我们可以使用十进制当做中间值进行相互转换,当然在有些情况下,这样的转化方式会导致数值越界,因此有时需要使用模拟除法,使用字符串进行进制的转化。

​ 除去十进制作为媒介的转换方式以外,还存在m进制和n进制直接转换的情况,这种情况实际上不常见,但是确实也存在,因此我在这里进行详细的整理。

7.不使用十进制作为媒介的m进制和n进制之间的直接转化

​ 这个转化方式对我来说理解起来有点不容易,但是在理解之后就会发现这其实是一个相当简单方便的算法。除去常规的常见十进制转换法,我们使用的直接转化法其实是一种更有普适性的进制转换法,在上文提到的其他进制向十进制转换也就是拆数发,其实是它的高级变种,是这种普适法则的一个特殊用法,现在我们来着重研究这一块。

十进制转十六进制:
十进制转其他进制的方式实际上就是用除法算式进行求余计算,如十进制的1320转化向十六进制,有:
1320 / 16 = 82 ...... 8
  82 / 16 =  5 ...... 2
   5 / 16 =  0 ...... 5
因此结果为528
而十六进制向十进制进行转换,实际上也是使用的这个方法:
528 / 10 = 84 ...... 0
 84 / 10 = 13 ...... 2
 13 / 10 =  1 ...... 3
  1 / 10 =  0 ...... 1
结果正好为1320

​ 由此可见使用除法算式的方式也可以得到转化值,和拆分得到的数据一样,实际上,除法算式和拆分法是一样的,只不过拆分法更加的简单明了,实际上,在上面的过程中,除法算式就是在不断的除10,这个过程实际上就像我们在十进制中求单个位一样,不断地以逢十进一的机制,寻找一个一个的单个位,第一个余数就是最高位,以此类推。而拆分法则是沿用了相反的思路,从16位的方向推进,直接将这个数字理解成一个十进制数,和十位数不同的只不过是它是逢16进一,它的每位数字是16*16…而不是10*10…然后按照十进制加和的方式进行累加即可。因此,我们在进行m进制转n进制时,就使用m进制不断地除以n并求余,直接使用除法算式解决,当然在计算时我们需要遵循m进制的运算法则。通常来讲,十进制以外的算数法则并不是很好理解且并不容易算对,因此在进行m和n进制之间的进制转换时并不建议使用这种方法。

8.总结

​ 总体上讲,进制转化的模式和十进制中求每位特别相似,就是用这个m进制数不断的除以自己的进制并求余即可。同时,我们可以换个角度看,我们可以直接用十进制的思路来理解m进制位数,进而使用十进制的方式来进行求解,这种理解方式实际上就是:**m进制的数字就是逢m进一,这个进制中的十位百位千位实际上就是m和m2,m3,它里边除了和十位数进位不同,其余的进位方式和计数方法都和十进制类似,因此我们套用十进制的划分表示法,就可以表示这些其他进制。**而除法算式则是反过来推导,它实际上也是使用了十进制的思路,只不过它是套用了十进制的求单个位的思路,通过m位来进行新的进制划分,进而求出m进制的每个位,然后对这些位进行重新组合,就可以得到m进制数字了。

​ m进制的数字,套入除法算式,对n求余且使用n进制的计数法,就可以像十进制不断除10那样得到n进制的每个位,进而将这个数字转化为n进制数。

​ 这是不是很麻烦,所以还是用十进制做中间值最方便了,同时低进制转高进制时,当高进制时低进制的平方倍关系时,如2进制转4进制,4进制转16进制等,可以直接通过位数进行转换,如2进制转16进制,2进制的四个位就可以表示一个十六进制,这是因为十六进制逢十六进一,二进制逢二进一,而二进制中每过四个位,就会向十六进制中每逢十六进一次一,或者说二进制中的每四个位就可以完全表示十六进制中的一位中的任何数字,因此这样的关系可以进行直接转化,其余同理。

你可能感兴趣的:(JAVA核心技术,数学,java)