最近看数据结构的书,回顾下以前学的东西。无意间翻到了stack这章,我就在想,为什么要使用栈这种数据结构?它的底层不也就是数组或者链表来实现的吗?于是,希望能从书中找到答案(其实我之前也猜想,无非是和pattern类似,封装了一层,便于使用嘛)。书里讲了几个例子来说明stack的用法。其中一个就是"数制转化",一个古老的话题,学计算机的都会知道。结尾处作者如是说,摘抄如下:栈的引入简化了程序设计的问题,划分了不同的关注层次,使思考范围缩小了,而用数组不仅掩盖了问题的本质,还要分散精力去考虑数组下标增减等细节问题!
ok,扯远了点。只是想记录下,方便以后查阅。进入正题!如何才能够快速地进行进制的转化(当然是针对人的思维来说)?参考了两篇篇文章(http://blog.163.com/zh_jie/blog/static/164715022201093010755919/和http://shakesmin.javaeye.com/blog/57978),自己也思考了下,暂总结如下:
进制主要分为10进制、2进制、8进制、16进制。为什么会有不同的进制?10进制便于人类计数,但是计算机却很难识别。而计算机则很容易识别2进制并进行计算。这两种极端情况下又出现了8进制和16进制,why?因为有的时候人像看清计算机计算的东西(2进制表示),但是2进制有个缺点,就是数字大了后会变得很长,很难理解!所以人们就选取了折中的方式,8进制和16进制。
小结:由此可以看出,10进制转2、8、16进制相对而言要难些,而2、8、16进制之间相互转化则要容易些~
先从容易的开始。2、8、16进制之间相互转化。(借用上面引用的两则文章可知,1111这个2进制数的每位权值分别是8、4、2、1,这个很有用!)
2 to 8:以10010为例,要转成8进制,则从右向左看,每3个为一组,不足的补零,变成010 010,加上权值后为22,即为8进制数!
8 to 2:与上面的相反,以27为例,要转为2进制,则每个位作为一组分开,变成2 7,通过权值变换后为010 111(为1的替换为权值,然后相加等于7,则4+2+1,即每个位都是1,故为111),最后得到的2进制数为010111,去掉左边的0,最终结果是10111。
2 to 16: 以101110为例,要转成16进制,类似,从右向左看,每4个为一组,不足的补零,变成0010 1110,加上权值后为2E,有个规律,8进制的各个位<=7,16进制的各个位<=15,也就是说16进制中的数可以是1、2、3、4……9、A、B、C、D、E、F。
16 to 2:以EF为例,每个为作为一组分开,变成E F,通过权值变换后为1110 1111,最后得到的2进制是 11101111
8 to 16:以27为例,8进制和16进制之间的转换需要用2进制来作为过渡,先转成2进制为010 111,然后从右向左数,将现在的3个一组变为4个一组,不足的补零,变为0001 0111,然后权值变换后为1 7,也就是16进制数 17
16 to 8:类似,只是反过来就不再赘述了~
以上就是2、8、16进制之间的转换,很简单。下面介绍10进制向2、8、16进制的转换。
同上面那样,为了快速计算,我们需要了解一些比较常用的式子。如下所示:
21=2 ; 22=4 ; 23=8 ; 24=16 ; 25=32 ; 26=64 ; 27=128 ; 28=256
10 to 2:以52为例,52-32-16-4 = 0,也就是说52可以分解为4+16+32,而32对应的是25,因而最高位是第6位为1,即32是100000(或者说后面跟5个0)。这样52可以分解为100000+10000+100=110100(2)
通过这种方式转为2进制之后就很容易再转为8、16进制。
另外一种做法是 取余法。如下所示(图片来自网络,版权属于原作者!)
这种做法适合于编程实现10进制与2、8、16进制的转化。