今天正好复习到了计组的数据表示和运算,各种进制之间、整数小数部分算来算去头都疼,好在王道书上给了两个计算的便捷方法:
针对整数部分有“短除法”,也叫“除基取余法”,除基取余,先余为低,后余为高。
针对小数部分有“乘基取整法”,乘基取整,先整为高,后整为低。
有了这俩办法做题是不成问题了,很快就能算出结果,但是这只是表面,对于喜欢研究原理钻牛角尖的我来这是不够的。
那我问你,为什么十进制要除以目标进制的基数,这样得出的余数就是我们需要的目标数了?为什么?如果把目标二进制换成八进制呢,三进制五进制又会怎么样?换成其他进制还可以吗?
那我再问你,为什么小数部分又要乘目标进制的基数?不是除了?为什么这样就可以出结果了??
一、深入“短除法”
要想解决上面的疑问,我们就要回到最原始的“数值表示”中去了,要把一个数字“解剖”,看看最底层的东西。这是王道计组中给出的相关内容:
这里我们只用关注“基数”“位权”这两个词的定义即可,重点在 r 进制数的数值表示上,这个非常非常重要,由图可以知道,一个 进制数可以表示为:
其中, 是第
位上的数字
,
是目标进制的基数。这里跟书上标的不太一样,但意思不变,只是方便我自己理解,嘿嘿。
现在我们来看短除法的具体过程:
首先进行第一次除法:将十进制数 除以目标进制的基数
,得到商
和余数
。表示为:
根据上面的 进制表示,哎,我们可以看到
正好是
进制数中的最低位
,因为其他所有项都包含因子
。所以
。
接着进行第二次除法:将上一步得到的商 再除以基数
,得到商
和余数
。表示为:
正好可以替换上面式子中的内容,带入就变成了:
这时,我们可以看到 正好是
进制数中的次地位
。所以,
。
以此类推,我们继续用新的商除去以基数 ,得到的余数依次是
进制数从低位到高位的数字。假设我们进行了
次除法,直到商为 0:
最后的商是0,余数是最高位,你发现了吗,每一次除以基数 所得到的余数,都是当前数在
进制表示下,还没有被
整除的部分,正好对应了
进制的最低位(
的系数)。而每一次除法得到的商,实际上是原数去掉最低位后,剩余部分所代表的数值(相当于原数右移一位,或者说除以了
)。我们对这个商继续进行相同的操作,就是在提取新的最低位。
将这些式子从下往上代回,可以得到:
这里的 ,
,
,
,
就是我们通过短除法得到的余数序列。由于我们是先得到
(最低位),然后是
,以此类推,最后得到
(最高位),所以我们将这些余数倒序排列,就得到了目标进制的表示:
。
二、深入“乘基取整法”
有了上面对短除法的解释,乘基取整法也就很好理解,它实际上就是“反过来的”短除法。同样基于数制中每一位权重的定义。为方便理解,我们约定一个 进制的小数可以表示为:
其中, 是小数点后第
位上的数字
,
是目标进制的基数。
下面的步骤和短除法几乎是一样的,不同的地方在于把除换成了乘:
第一次乘法,将十进制小数 乘以目标进制的基数
。
我们可以看到,乘积的整数部分正好是 进制小数的第一位
,我们将这个整数部分
取出来。剩余的小数部分
。
第二次乘法,将上一步得到的小数部分 再乘以基数
。
这次得到的是 。我们将
取出来。以此类推,我们可以得到:
把取出的整数部分 顺序排列,就得到了目标进制小数的表示:
。
大功告成!我们把两种算法进行了细致的剖析,得知了其背后的原理,乍一看很唬人,但是我们只要知道其基本表示原理很容易理解了。
三、进制转换背后的原理
但是!我们还剩一个问题,为什么对这个目标基数 进行操作就能实现转化呢?也就是,为什么我们通过“乘或除”一个
,就能实现一个进制转化乘另一个进制呢?明明两个基数都不一样,比如一个10一个2,或者一个5一个8,这似乎看起来毫无道理!
如果你跟我一样有这个问题,那么很高兴我们是一路人,其实,这个问题的核心在于:
数制的本质定义 和 我们如何“拆解”一个数。
回顾一下,我们都知道,任何一个整数 在
进制下的表示形式是:
其中 是第
位上的数字
,
是目标进制的基数。任何一个数都可以这样表示,这是个通式!也就是说,你可以把任何一个数表示成这种形式。比如数字 16 ,
在十进制下,它就是「16」,代表 ;
而在八进制下呢?它变成了「14」,代表 ;
十六进制呢?它又变成了「22」,代表 ;
进制的转换说到底只是一种“解释方式的改变”,而解释这个数字的“方式”,就是你的进制 ,你想转化成什么进制,就用什么进制去“解释”它,这个逐渐改变解释的过程,就是“短除法”和“乘基取整法”!当然或许还有其他的方法,这里不多解释了。
到此为此,我们已经详细了解了计算机中数值的表示和进制之间相互转化的原理,探讨了两种转化方式背后的详细流程,希望对你有帮助。作者本人也是边学边总结,如果有不对的地方,欢迎留言讨论。