大数问题之加减乘除

#include <iostream>

#include <stdio.h>

#include <string.h>

using namespace std;

const int MAXSIZE = 1000;//注意边界条件,根据具体问题,更改MAXSIZE

char str1[MAXSIZE], str2[MAXSIZE],str3[MAXSIZE];

void Add(char *str1, char *str2, char *str3);

void Minus(char *str1, char *str2, char*str3);

void Mul(char *str1, char *str2, char *str3);

void Div(char *str1, char *str2, char *str3);

int main(void) {

 

       intt;

       cin>> t;

       for(int i = 1; i <= t; i++) {

              cin>> str1 >> str2;

              cout<< "Case " << i << ":" << endl;

              Minus(str1,str2, str3);

              cout<< str1 << " - " << str2 << " = "<< str3 << endl;

              ;

              if(i != t)

                     cout << endl;

 

       }

       return0;

}

 

 

 

 

//加法

void Add(char *str1, char *str2, char *str3){ // str3 = str1 + str2;

       inti, j, i1, i2, tmp, carry;

       intlen1 = strlen(str1), len2 = strlen(str2);

       charch;

       memset(str3,'0', sizeof(str3));

       i1= len1 - 1;

       i2= len2 - 1;

       j= carry = 0;

 

       for(; i1 >= 0 && i2 >= 0; ++j, --i1, --i2) {

              tmp= str1[i1] - '0' + str2[i2] - '0' + carry;

              carry= tmp / 10;

              str3[j]= tmp % 10 + '0';

       }

       while(i1 >= 0) {

              tmp= str1[i1--] - '0' + carry;

              carry= tmp / 10;

              str3[j++]= tmp % 10 + '0';

 

       }

       while(i2 >= 0) {

              tmp= str2[i2--] - '0' + carry;

              carry= tmp / 10;

              str3[j++]= tmp % 10 + '0';

       }

       if(carry)

              str3[j++]= carry + '0';

       str3[j]= '\0';

 

       for(i = 0, --j; i < j; ++i, --j) {

 

              ch= str3[i];

              str3[i]= str3[j];

              str3[j]= ch;

       }

}

 

 

 

 

//减法:

void Minus(char *str1, char *str2, char*str3) { // str3 = str1-str2 (str1 > str2)

       inti, j, i1, i2, tmp, carry;

       intlen1 = strlen(str1), len2 = strlen(str2);

       charch;

memset(str3, '0',sizeof(str3));

       i1= len1 - 1;

       i2= len2 - 1;

       j= carry = 0;

 

       while(i2 >= 0) {

 

              tmp= str1[i1] - str2[i2] - carry;

              if(tmp < 0) {

                     str3[j]= tmp + 10 + '0';

                     carry= 1;

              }else {

                     str3[j]= tmp + '0';

                     carry= 0;

              }

              --i1;

              --i2;

              ++j;

       }

       while(i1 >= 0) {

              tmp= str1[i1] - '0' - carry;

              if(tmp < 0) {

                     str3[j]= tmp + 10 + '0';

                     carry= 1;

              }else {

                     str3[j]= tmp + '0';

                     carry= 0;

              }

              --i1;

              ++j;

       }

       --j;

       while(str3[j] == '0' && j > 0)

              --j;

       str3[++j]= '\0';

 

       for(i = 0, --j; i < j; ++i, --j) {

 

              ch= str3[i];

              str3[i]= str3[j];

              str3[j]= ch;

       }

}

 

 

 

 

//乘法:

void Mul(char *str1, char *str2, char *str3){

       inti, j, i1, i2, tmp, carry, jj;

       intlen1 = strlen(str1), len2 = strlen(str2);

       charch;

       memset(str3,'0', sizeof(str3));

       jj= carry = 0;

 

       for(i1 = len1 - 1; i1 >= 0; --i1) {

              j= jj;

 

              for(i2 = len2 - 1; i2 >= 0; --i2, ++j) {

                     tmp=

 

                     (str3[j]- '0') + (str1[i1] - '0') * (str2[i2] - '0') + carry;

                     if(tmp > 9) {

                            carry= tmp / 10;

                            str3[j]= tmp % 10 + '0';

                     }else {

                            str3[j]= tmp + '0';

                            carry= 0;

                     }

              }

              if(carry) {

                     str3[j]= carry + '0';

                     carry= 0;

                     ++j;

              }

              ++jj;

       }

       --j;

 

       while(str3[j] == '0' && j > 0)

              --j;

       str3[++j]= '\0';

       for(i = 0, --j; i < j; ++i, --j) {

 

              ch= str3[i];

              str3[i]= str3[j];

              str3[j]= ch;

       }

}

 

//除法:

 

void Div(char *str1, char *str2, char*str3,char *str4)//str3保存商,str4保存余数

{

    inti1, i2, i, j, jj, tag, carry, cf, c[MAXSIZE];

    //c存商

    intlen1 = strlen(str1), len2 = strlen(str2), lend;

   char d[MAXSIZE];

   //d  当前被除数,

   memset(c, 0, sizeof(c));

   memcpy(d, str1, len2);

   lend = len2;

    j =0; //商的位数,含前导0

   for( i1=len2-1; i1 < len1; ++i1 )

    {

       //i1:商在原被除数的位置

       if( lend < len2 )

       {

           //被除数位数小于除数位数,扩充被除数位数

           d[lend] = str1[i1+1];

           c[j] = 0;

           ++j;

           ++lend;

       }

       else if( lend == len2 )

       {

           jj = 1;//被除数与除数位数相同且大于除数

           for( i=0; i < lend; ++i )

           {

                if( d[i] > str2[i] ) break;

                else if( d[i] < str2[i] )

                {

                    jj = 0;

                    break;

                }

           }

           if( jj == 0 )

           {

                //被除数小于除数,被除数再扩充一位

                d[lend] = str1[i1+1];

                c[j] = 0;

                ++j;

                ++lend;

                continue;

           }

       }

       if( jj==1 || lend > len2 )

       {

           //被除数大于除数,或者长度比除数多1位

           cf = jj=0;

           //cf : 是否可以进行除法

            while( d[jj] <= '0' && jj< lend ) ++jj;

           //找到被除数的第一个非0数字

           if( lend-jj > len2 )

                cf = 1;  //被除数长度大于除数

           else if( lend-jj < len2 )

                cf = 0; //被除数长度小于除数

           else

           {

                //被除数长度等于除数

                i2 = 0;

                cf = 1;

                for( i=jj; i < lend; ++i )

                {

                    if( d[i] < str2[i2] )

                    {

                        //被除数小于除数

                        cf = 0;

                        break;

                    }

                    else if( d[i] > str2[i2])

                    {

                        break;

                    }

                    ++i2;

                }

           }//else

           while( cf )

           {

                //被除数大于除数,求被除数/除数的商(商是1位数)

                i2 = len2-1;

                cf = 0;

                for( i=lend-1; i >=lend-len2; --i )

                {

                    //从末位向前 被除数-除数

                    d[i] = d[i]-str2[i2]+'0';

                    if( d[i] < '0' )

                    {

                        d[i] = d[i]+10;

                        carry = 1;

                        --d[i-1];

                    }

                    else carry = 0;

                   --i2;

                }

                ++c[j]; //累计可以的(被除数-除数)的次数,即商

                //以下代码与上面部分重复,判断被除数是否大于除数

                jj=0;

                while( d[jj] <= '0'&& jj < lend ) ++jj;

                if( lend-jj > len2 ) cf = 1;

               else if( lend-jj < len2) cf = 0;

                else

                {

                    i2 = 0;

                    cf = 1;

                    for( i=jj; i < lend; ++i)

                    {

                        if( d[i] < str2[i2])

                        {

                            cf = 0;

                            break;

                        }

                        else if( d[i] >str2[i2] )

                        {

                            break;

                        }

                        ++i2;

                    }

                }//else

           }//while

 

           jj = 0;

           //整理余数,得到新的被除数

           while( d[jj] <= '0' && jj < lend ) ++jj;

           for( i=0; i < lend-jj; ++i ) d[i] = d[i+jj];

           d[i] = str1[i1+1];

           lend = i+1;

           ++j;

       }//if

   }//for

    i =tag = 0;

   while( c[i] == 0 ) ++i;

   for( ; i < j; ++i, ++tag ) str3[tag] = c[i]+'0';

   str3[tag] = '\0';

//以下内容补充 by lyh:13/5/19

// 数组d 保存余数

    i = tag = 0;

   while( d[i] == '0' ) ++i;

   while( d[i] != '\0' )

       str4[tag++] = d[i++];

   str4[tag] = '\0';

//商为0时正确返回

   if(str3[0]=='\0')

    {

       str3[0]='0';

       str3[1]='\0';

    }

//余数为0时正确返回

   if(str4[0]=='\0')

    {

        str4[0]='0';

       str4[1]='\0';

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值