zoukankan      html  css  js  c++  java
  • 大数四则运算之大数相减

    1.引言

        本文主要针对自己学习大数处理过程中的一些思路进行整理记录,以备后忘。大数相减与大数相加相比,需要考虑借位问题。处理借位需要考虑二种情况,假设被减数为Sub1,减数为Sub2,这些都是以字符串形式存储的大数。 则大致要考虑二种情况的借位:

     1) Length of Sub1 is greater or equal to Length of Sub2: 此时需要考虑两种借位:一种是Sub1大数大于Sub2大数,则Sub1最高位(Sub1首位置)无需再进一步借位,此种状况比较好处理;另一种是Sub1大数小于Sub2大数,则Sub1最高位还需进一步借位,此种情况处理稍微复杂,在下面将展开讨论.

    2)Length of Sub1 is less than Length of Sub2: 此种情况即Sub1最高位还需进一步借位情况,我们在此假设Sub1长度不足Sub2长度的部分填充0,以

    "123"(sub1) - "456789"(sub2)为例,如下简图所示,最终结果应该为"456666",还要加负号表示结果为负数。在此过程中还要引入一个基数作为调整,基数设定原理是以第一种情况所算出的最终值为参考,如下图参考基数所述,其实只要理解相减过程,此步不难理解。

    具体代码如下:

    #include <iostream>
    #include <string.h>
    using namespace std;
    const int N=1005;
    
    void Sub(char *p1,char *p2,int *p3)
    {
        int i,j,k=0;
        
        int bit=0,t=0; //bit:表示借位,1:表示需要借位,0:表示不需要借位。t:存储中间计算的位相减值
        int len1=strlen(p1);  //被减数的长度
        int len2=strlen(p2); //减数的长度
        
        for(i=len1-1,j=len2-1;i>=0 && j>=0;--i,--j) //此为循环遍历两数,分别对位进行相减操作
        {
            t=(p1[i]-'0')-(p2[j]-'0')-bit;    //计算两个位之间的差值,同时要考虑借位
            
            if(t<0)  //如果t小于0,表示需要借位,bit赋值为1,且最终相减结果需加10作为调整并存储到p3数组中,自己用笔画一下就好理解.
            {
                bit=1;
              //例:123-456,t相减实际值分别为-3(3-6-0(bit)),-4(2-5-1(bit)),-4(1-4-1(bit)),加10调整后为:
               // 7,6,6,由于最高位相减后还bit为1即还需借位,  因此还需调整,转换为第一种情况,即用1000-667=333,且结果为负    
                p3[k++]=t+10;        
            }
            else
            {
                bit=0; //相减为正,则无需调整,直接将t赋给p3对应位。
                p3[k++]=t;
            }
            
        }
        while(i>=0)  //strlen(p1)>strlen(p2) ,result is greater than zero
        {
            t=p1[i]-'0'-bit;
            if(t<0)
            {
                bit=1;
                p3[k++]=t+10;
            }
            else
            {
                bit=0;
                p3[k++]=t;
            }
            i--;
        }
        while(j>=0) //strlen(p1)<strlen(p2),result is less than zero
        {
            t=10-bit-(p2[j]-'0');        
            p3[k++]=t;
            j--;
        }
        if(bit==1)  //对仍有进位的情况考虑,主要分两种:一种是strlen(p1)<strlen(p2),另一种是p1-p2<0,这两种情况bit为1
        {
            p3[0]=10-p3[0];
            for(i=1;i<k;++i)
            {
                p3[i]=10-p3[i]-bit;
            }        
        }
        if(bit==1)
            cout<<"-";
        for(i=k-1;i>=0;--i)
            cout<<p3[i];
        cout<<endl;
    }
    int main()
    {
        char c1[N],c2[N];
        int a[N];
        int i,j;
        while(cin>>c1>>c2)
        {
            memset(a,0,sizeof(a));
            Sub(c1,c2,a);
        }
        return 0;
    }

    2. 总结:

        整个过程都是自己通过在纸上把各种情况考虑后转换成的代码,对于自己来说也是个熟悉的过程,希望能对大家有所帮助。

    作者:ballwql
    本文为作者原创,版权所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    java中商业数据计算时用到的类BigDecimal和DecimalFormat
    Git和SVN之间的区别
    ubuntu 交叉编译arm linux 内核小例子
    交叉编译工具链介绍《Building Embedded Linux Systems》
    交叉编译工具链命名详解
    oracle数据库分页总结
    oracle随机数(转)
    oracle函数nvl, nvl2, nullif
    反转数字, 即输入123, 返回321
    java试题
  • 原文地址:https://www.cnblogs.com/ballwql/p/3032090.html
Copyright © 2011-2022 走看看