大整数减法计算思路与算法实现

二、大整数减法

1、思路

大整数减法的思路,就是竖式减法a-b,有2种大情况:

  • a大于b
  • a小于b

第一种情况a>=b,就是逐项相减。如果够减就直接相减;如果本位不够减,寻找下一位借位

  • 下一位>0,向下一位借位(a[i+1]--),加10到本位上再相减;
  • 下一位<0,循环查询下下一位(用while语句),找到大于0的那一位,向那一位借位(a[i+k]--),加10到本位上再相减,同时把本位下一位到借位位之间的数置为9。
  • 如果循环到数组末尾仍然借不到位,那么就是被减数不够减,需要交换被减数和减数,同时计算-(b-a)

第二种情况a小于b,交换对象a和b(这里中间变量需用对象变量bigNum tmp),然后算-(b-a)

2、 算法

运用数组存储两个操作数,先判断情况,再右对齐逐位相减

void operator- (bigNum & result,bigNum & b)
    {
        int length1=result.len,length2=b.len;
        bigNum tmp1,tmp2;
        tmp1=result;
        tmp2=b;                                /*保护现场*/
        if(length1>=length2){                  /*情况1:如果a>b或者a足够减b*/ /*注意还有区分虽然长度一样,但实际借不到位的情况,如2-3*/
            for( int i = 0;i < MAX_LEN+10 ; i ++ )
            {
                if(result.sInt[i] >= b.sInt[i]){/*如果够减*/
                    result.sInt[i] -= b.sInt[i]; //逐位相减
                    continue;
                }

                else{                           /*不够减*/
                    if( result.sInt[i+1] > 0 )  //如果下一位够减
                    {                           //就借位
                        result.sInt[i] += 10;    //借位
                        result.sInt[i] -= b.sInt[i]; //逐位相减
                        result.sInt[i+1]--;
                    }
                    else{                         /*如果下一位不够减,试探下下位 */
                        int k=1;
                        while(result.sInt[i+k] == 0)
                            k++;
                        if(i+k>= MAX_LEN+10){/*注意还有区分虽然长度一样,但实际借不到位的情况,如2-3*/
                            result=tmp2;      /*情况3:a不足以减b,计算-(b-a)*/
                            b=tmp1;            /*恢复现场*/ 
                            cannotSub=1;      /*布尔变量,标记被减数小于减数*/
                            result-b;         /*恢复现场时已经交换了位置*/
                            if(o=='-')        /*除法也会调用减号函数,只有在减号下才打印负号*/
                                cout<<"-";
                            break;
                        }

                        if( result.sInt[i+k] > 0 )  //如果下下位够减
                        {                           //就借位
                            result.sInt[i] += 10;    //借位
                            result.sInt[i] -= b.sInt[i]; //相减
                            result.sInt[i+k]--;
                            for(int j=i+1;j<=k+i-1;j++){
                                 result.sInt[j]=9;   //并且中间的0全部变为9
                            }
                        }
                    }
                }
            }
        }
        if(length1<length2){   /*情况2:如果a<b,结果为-(b-a) */
            bigNum tmp;  /*简洁*/
            tmp=result;
            result=b;
            b=tmp;
            result-b;
            if(o=='-')
                cout<<"-";  
        }

        result.len=0;
        for(int i=MAX_LEN+9;i>=0;i--){
            if(result.sInt[i]!=0){  
                result.len=i+1;   /*除法要用到长度,数组长度更新*/
                break;
            }
        }
    }
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值