• 进制的意义和算法


    1、问题

    1.1 苹果装箱

    小明家摘了123个苹果,10个苹果可以装满1箱,10箱苹果就可以装满1车拉到批发市场去出售了,问这些苹果一共能装满几车,几箱,还剩几个苹果?

    聪明的朋友可能直接给出答案是1车2箱,最后剩3个苹果。

    计算的过程:

    123个 / 10 = 12箱,余3个苹果

    12箱 / 10 = 1车,余2箱

    当然,有朋友会立即指出,为啥要这么SB的算,123的百位1不就是1车,十位2 = 2箱,个位3 = 3个

    没错,这就是123这个数表示的意义。百位表示车的数量,十位表示箱的数量,个位表示剩下苹果个数。

    假设我们的苹果每满10个就必须装箱,每满10箱就必须装车卖掉(否则就烂了),而这个装箱装车就是我们所谓的进位。

    1.2 银行换钱

    小明现在有123个1分硬币,想去银行换成整的,最后可换得1元2毛零3分。

    这里同样的,1元即是百位的数,2毛即是十位的数,3分就是位的数,这就是数字说代表的现实意义。

    2、位的意义及数学概念

    2.1 万能公式

    所有的十进制数都可以用一个公式来表示:

    image

    指数n = an所在的位数,个位n=0,十位n=1,依次递增

    an = 对应位数上的数值

    10 = 十进制

    那么就有一个万能公式来描述所有进制的记数:

    image

    2.2 问题1.1的另一个思考

    123个苹果,如果交给计算机去计算能装满几车,几箱,还剩几个苹果?

    这时候计算机不能用眼睛去看出123这个数字说表示的意义了,但发现用1.1的计算过程计算机可以描述出来:

    a =  num % 10;           //a 依次等于个、箱、车
    num = num / 10;
    Loop…

    同时可能有的朋友有一种想法:

    车的指数n=2,貌似把num / 100 = 1 就是车的数量

    但是有2个问题:

    • 计算机不知道123的数字的长度,假设我们是23个苹果,再去除100就是得到的商是0,0一般是自动忽略的,故此步是多余计算的
    • 如果要求箱的数量,num / 10 = 12,这就不对了

    如果求余数也会有类似的问题,但求最后剩下的苹果个数时,余数总是对的:

    123 % 10 = 3 个

    所以才有每次除10的操作,依次让箱、车的位变为个位,也就是编程中的右移操作,然后再求余就没什么问题了,这时候我们多想,要是10进制也有位移操作符多好啊

    2.3 10进制的移位操作

    当我们把 num 除 10时(余数丢弃,不处理小数),会有一个神奇的现象:

    123 / 10 = 12

    12 / 10 = 1

    这实际上已经是在进行右移操作了,所以10进制右移即是将其除10(左移即是将其乘10),而其余数即是被移除的最低位的数值

    2.4 数学证明(注意不涉及小数计算,余数丢弃)

    image

    此时a1变为个位了,下次再继续除10,就会将a1移出了

    于是,我们就能利用该方法不断的将数右移,然后移出的余数就是对应位上的数的值了。

    3、应用

    上面说了一堆公式和理论,没看出有啥实际的用处,而理论是为了实践服务的,那么下面就让我们来看看它如何干活的吧

    3.1 计算问题1.1中的苹果装箱问题

    void    CTestMath::LoadApple(unsigned uNum)
    {
        int            nSize = 0;
        unsigned    uAppleArray[3] = {0};
    
        while (uNum)
        {
            uAppleArray[nSize] = uNum % 10;
            uNum /= 10;
            nSize++;
        }
    
        printf("The apples can load to %d car, %d box, left %d apple
    ", uAppleArray[2], uAppleArray[1], uAppleArray[0]);
    }

    3.2 将一个num以10进制形式的字符输出(和苹果装箱问题类似)

    int    CTestMath::OutputDecimalNum(unsigned uNum, char* pszNum)
    {
        int    nSize = 0;
    
        while (uNum)
        {
            pszNum[nSize] = (uNum % 10) + '0';
            uNum /= 10;
            nSize++;
        }
    
        //因为是从低位开始处理,所以放入pszNum的数是倒置的,需要对调一下
        for (int i = 0; i < nSize / 2; i++)
        {
            char    cTemp = pszNum[i];
            pszNum[i] = pszNum[nSize - 1 - i];
            pszNum[nSize - 1 - i] = cTemp;
        }
    
        pszNum[nSize] = NULL;
        return    nSize - 1;
    }

    4 16进制

    4.1 回到问题1.1,随着小明卖苹果有钱了,新换了一辆大车,能装16箱苹果,同时增大了箱子,每箱能装16个苹果,此时123个苹果能装能装满几车,几箱,还剩几个苹果?

    image

    此时我们发现,从123的字面上不能直接给出答案了,怎么办?

    采用1.1中类似的计算方法:

    123个 / 16 = 7箱,余11个苹果,用16进制记为B

    7箱 / 16 = 0箱,余7箱

    所以答案是能装满0车,7箱,剩B(11)个苹果,记为数字"7B"

    此时我们再来看"7B"这个数,就可以用1.1中的方法看出,十位"7"即为箱数,个位B即为剩余的苹果数,可以预计,百位即为车数,这就是不同进制的数的实际意义。

    实际上,在我们的实际生活中,我们也有其他进制的应用,如时钟,秒到分,分到小时,即是60进制的,如要问123456秒等于多少小时,多少分,多少秒?即可用类似的算法解决。

    4.2 数学证明

    回到我们的万能公式,将其转化为16进制的形式:

    image

    此公式依然成立,所以我们能用同样的方法解决16进制中的问题

    4.2 将10进制数转化为16进制数形式字符

    int    CTestMath::DecimaltoHexadecimal(unsigned uNum, char* pszHexNum)
    {
        int        nSize = 0;
        char    cTemp = 0;
    
        while (uNum)
        {
            cTemp = (uNum % 16);
    
            //如果数值大于9,则要用ABCDEF来表示
            if (cTemp > 9)
            {
                cTemp += ('A' - 10);
            }
            else
            {
                cTemp += '0';
            }
    
            pszHexNum[nSize] = cTemp;
            uNum /= 16;
            nSize++;
        }
    
        //因为是从低位开始处理,所以放入pszNum的数是倒置的,需要对调一下
        for (int i = 0; i < nSize / 2; i++)
        {
            cTemp = pszHexNum[i];
            pszHexNum[i] = pszHexNum[nSize - 1 - i];
            pszHexNum[nSize - 1 - i] = cTemp;
        }
    
        pszHexNum[nSize] = NULL;
        return    nSize - 1;
    }
  • 相关阅读:
    Oracle Golden Gate 系列十四 监控 GG 状态 说明
    Oracle Golden Gate 系列十六 配置 GG 安全 说明 与 示例
    带宽计算方法 及 大B与小b 说明
    带宽计算方法 及 大B与小b 说明
    Oracle LOB 详解
    Oracle bootstrap$ 详解
    Oracle 10g 中 X$KCVFH 说明
    RMAN 备份报错 RMAN06207 RMAN06208 解决方法
    Oracle Golden Gate 系列十三 配置GG进程检查点(checkpoint) 说明
    Oracle Lifetime Support(支持生命周期) 说明
  • 原文地址:https://www.cnblogs.com/organic/p/5237085.html
Copyright © 2020-2023  润新知