码迷,mamicode.com
首页 > 其他好文 > 详细

大整数四则运算

时间:2017-01-04 21:45:10      阅读:374      评论:0      收藏:0      [点我收藏+]

标签:行存储   and   导出   define   ros   cas   int   strncmp   com   

============

日后再写!先将设计思想留下

=============

 

定义并实现超长整数类double long,要求如下:

64位数据长度,有符号

支持+、-、*、/运算

支持+=、-=、/=运算

支持cin>>和cout<<操作

 

 

首先,我们的运算对象是大整数并且要支持cout<<和cin>>操作,数组和链表是可选择项。在这里我们用数组。数组有int型和char型,选哪个好呢?只能选char型,因为我们的大整数是有符号位的,必须用一个char字符来存储。而int型是无法进行存储的。再明确输入的第一个运算数A,输入的第二个运算数B,四则运算后得出的结果是C。

 

其次,我们的符号在运算的时候不能代入计算,那么我们就要用一个数组K[2]来存储它,将运算数A和B先当成正数来计算(详情见下文),最后根据情况在结果前面添加正负号,听的很迷糊?没关系,看看下面你就知道了:

*,/ 运算时,只需考略A和B的符号,大小不必考虑:

 (1).若两运算数的符号相同(即+A,+B或者-A,-B),那么得出的结果也为正的,即+C。

 (2).若两两运算数的符号不同(即+A,-B或者-A,+B),那么得出的结果是负的,即-C。

 

+,- 运算时,既要考虑A和B的正负号,又要考虑大小:

 若两运算数的符号同为正(即+A,+B):

   (3).加运算直接竖式相加即可。

   (4).减运算首先要考虑两数的大小,若A>=B,则直接减运算,若A<B,则进行B-A运算。

 

 若两运算数的符号同为负(即-A,-B):

   (5).加运算:(-A)+(-B)=(-C),去掉括号后运算变成(+A)+(+B)=(+C)的运算。最后将结果变成(-C)即可。

   (6).减运算就变成了一个正数减去另一个正数的情况,具体见情况(4)。

 

 若两运算数的符号同为负(即+A,-B或者-A,+B):

  (7).加运算:将正数放到前面,负数放到后面,加运算就变成了减运算,具体见情况(4)。

  (8).减运算第一种情况:(+A)-(-B)。去掉括号(-B)就变成了(+B),这就成了加运算,具体见情况(3)。

  (9).减运算第二种情况:(-A)-(+B)。去掉括号后推导出-[(+A)+(+B)]运算,具体见情况(5)。

 

运算数全为正数时的四则运算:

?加法:从低位到高位依次进行竖式相加运算,低位的数分别为m,n,借位初始化为零;若相加的结果k(m+n)超过十,那么向前一位进(k-10)位,借位即(k-10)。将当最后一位(即最高位)算完时,若还是超过十,则不要忘了为进位分配一个存储空间。要注意:须判断出运算数A和B的长度作为循环的基础。

 

减法:从低位到高位依次进行竖式相减运算,低位的数分别为m,n,借位初始化为零;若减的结果k(m-n)小于零,那么就必须向前面相邻的高位借一位,

同时下一次运算时记住借位的高位要减一位。减运算也要控制好循环条件,否则当A<B, (A-B)<0时,输出的结果会出现未知0.

 

乘法:乘法也是从低位到高位依次竖式相乘,低位m1,n1相乘,记录结果,并且左移一位,以此类推,直到计算完最后一位,再将各项结果相加。得出最后结果。

 

除法:除法是从高位向低位依次减,减时以被除数长度为单位,从高位取出大于被除数的字符串,和被除数相减,减的次数为结果,余数从剩下的除数高位再取出几位做补位,直到大于被除数。再减,循环减到被减数大于余数加上补位,那么这个新的余数作为结果返回。

 

博主的代码如下:

 

技术分享
#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;

#define N 100

int c[2];
int a1[N];
int a2[N];
int a3[N];

int judgebig(char n1[N], char n2[N]);     //判断大小
void sub(char n1[N], char n2[N], int len1, int len2);
char toAdd(char n1[N], char n2[N]);        //
char toSub(char n1[N], char n2[N]);        //
void toMul(char n1[N], char n2[N]);        //
void toDiv(char n1[N], char n2[N]);        //
char toSub2(char n1[N], char n2[N]);
 
char Add(char n1[N], char[N]);
char Sub(char n1[N], char[N]);
void Mul(char n1[N], char[N]);
void Div(char n1[N], char[N]);

/*
将n1,n2的长度存入数组k 
返回n1,n2的比较结果 ,若大小相等返回0,n1>n2返回1,n2>n1返回2 
*/
int judgebig(char n1[N], char n2[N])
{
    int k[2];
    
//    统计n1的长度存入k[0],n2存入k[1]
    k[0] = strlen(n1);
    k[1] = strlen(n2); 
    
//    cout<<k[0]<<" "<<k[1]<<endl; 
    
    if(k[0] > k[1])            //n1长度 > n2长度 
    {
        return 1;
    }
    else if(k[0] < k[1])    //n1长度 < n2长度
    {
        return 2;
    }
    else if(k[0] == k[1])      //n1长度 = n2长度 
    {
        //两个数的位数相等,在从头开始判断 
        int k = strcmp(n1, n2);        //比较n1, n2的大小 
        if(k == 0)        //n1 = n2 
        {
            return 0;
        }
        else if(k > 0)     //n1 > n2
        {
            return 1;
        }
        else if(k < 0)    //n2 > n1
        {
            return 2;    
        }
        
    }
    
    return -1;
}

//用于除法的减 
void sub(char n1[N], char n2[N], int len1, int len2)
{
    int i=0;
    int j;
    while(1)
    {
        if(n1[i]==0)
            i++;
        else
        {
            j=i;
            break;
        }
    }
    
    for(;i<len2;i++)
    {
        n1[i]=n1[i]-n2[i]+0;
    }
    for(i=len2-1;i>j;i--)    //低位开始检测是否小于0
    {
        if(n1[i]<0)
        {
            n1[i]+=10;
            n1[i-1]--;
        }
    }
}

//加法2 
char toAdd2(char n1[N], char n2[N]) 
{
    int i,L,z;
    
    L=strlen(n1);
    for (i=0;i<L;i++)    //将n1转换为数字存入数组a1 
    {
        a1[i]=n1[L-1-i]-0;
    }

    L=strlen(n2);
    for (i=0;i<L;i++) //将n2转换为数字存入数组a2 
    {
        a2[i]=n2[L-1-i]-0;
    }

    for (i=0;i<N;i++) 
    {
        a3[i]=a1[i]+a2[i];
    }

    for (i=0;i<N;i++) 
    {
        if (a3[i]>=10) 
        {
            a3[i+1]+=a3[i]/10;
            a3[i]=a3[i]%10;
        }
    }

    z=0;
    for (i=N-1;i>=0;i--) 
    {
        if (z==0) 
        {
            if (a3[i]!=0) 
            {
                cout<<a3[i];
                z=1;
            }
        } 
        else 
        {
            cout<<a3[i];
        }
    }
    if (z==0) 
    {
        cout<<"0"<<endl;
    }
    return 0;
}

//
char toAdd(char n1[N], char n2[N])
{
    int i,L,z;
    
    L=strlen(n1);
    for (i=0;i<L;i++)    //将n1转换为数字存入数组a1 
    {
        a1[i]=n1[L-1-i]-0;
    }

    L=strlen(n2);
    for (i=0;i<L;i++) //将n2转换为数字存入数组a2 
    {
        a2[i]=n2[L-1-i]-0;
    }



    for (i=0;i<N;i++) 
    {
        a3[i]=a1[i]+a2[i];
    }

    for (i=0;i<N;i++) 
    {
        if (a3[i]>=10) 
        {
            a3[i+1]+=a3[i]/10;
            a3[i]=a3[i]%10;
        }
    }
    
//    cout<<n1<<"+"<<n2<<"=";
    
    //判断正负号 
    if(c[0] == c[1])     
    {
        if(c[0] == -)    //负相同时 
        {
            cout<<-;
        }
    }
    if(c[0] != c[1])    //一正一负 
    {
        if(c[0] == + & c[1] == -)
        {
            int m = judgebig(n1, n2);
            if(m == 1)    //n1》n2    
            {
                return toSub2(n1, n2); 
            }
            else if(m == 2)
            {
                cout<<-;
                return toSub2(n2, n1);        //注意调换了n1,n2的位置 
            }
        }
        else if(c[0] == - & c[1] == +)
        {
            int m = judgebig(n1, n2);
            if(m == 1)
            {
                cout<<-;
                return toSub2(n1, n2);    
            }
            else if(m == 2)
            {
                return toSub2(n2, n1);
            }
        }
    }


    z=0;
    for (i=N-1;i>=0;i--) 
    {
        if (z==0) 
        {
            if (a3[i]!=0) 
            {
                cout<<a3[i];
                z=1;
            }
        } 
        else 
        {
            cout<<a3[i];
        }
    }
    if (z==0) 
    {
        cout<<"0"<<endl;
    }
    
    return 0;        
}

//减法2 
char toSub2(char n1[N], char n2[N]) 
{
    int i,j,len1,len2;
    int a[N]={0},b[N]={0};
    len1=strlen(n1);
    len2=strlen(n2);
    
    for(i=len1-1,j=0;i>=0;i--,j++)    //变为数组 
    {
        a[j]=n1[i]-0;
    }
    for(i=len2-1,j=0;i>=0;i--,j++)
    {
        b[j]=n2[i]-0;
    }
    
    for(i=0;i<len1;i++)            //低位开始减,若减得结果<0,想高位借一(即加上十),高位减一(即减去十) 
    {
        a[i]=a[i]-b[i];
        if(a[i]<0)
        {
            a[i]+=10;
            a[i+1]--;
        }
    }
    
    i=len1-1;    
    while(a[i]==0)        //求i为结果的位数 
    {
        i--;
    }
    
    
    for(;i>=0;i--)
    {
        cout<<a[i];
    }
    return 0;
}

//
char toSub(char n1[N], char n2[N])
{
    if(c[0] == + & c[1] == +)
    {
        int m = judgebig(n1, n2);
        if(m == 2)        //n2 > n1
        {
            cout<<-;
            return  toSub(n2, n1); 
        }
    }
    else if(c[0] == - & c[1] == -)    //这里的递归调用的也不合理,递归会产生循环, 
    {
//        cout<<"#";
        int m = judgebig(n1, n2);
        if(m == 2)    //n2 > n1
        {
//            c[0] = ‘+‘;
//            return toSub(n2, n1);
            return toSub2(n2, n1);         //用toSub2合适,解决递归产生的循环问题 
        }
        else if(m == 1)
        {
            cout<<-; 
        }
        else if(m == 0)
        {
            cout<<0;
            return 0;
        }
    }
    else if(c[0] == + & c[1] == -)        //这里从tosub传入在间接传入toadd和直接从toadd传入是不一样的 , 有错 
    {
        return toAdd2(n1, n2);
    }
    else if(c[0] = - & c[1] == +)
    {
        cout<<-;
        return toAdd(n1, n2);
    }
    int i,j,len1,len2;
    int a[N]={0}, b[N]={0};        //要初始化为0 
    
    len1=strlen(n1);
    len2=strlen(n2);
    for(i = len1-1,j = 0; i >= 0; i--,j++)
    {
        a[j] = n1[i] - 0;
    }
    for(i = len2-1,j = 0; i >= 0; i--,j++)
    {
        b[j] = n2[i] - 0;
    }
    for(i = 0; i < len1; i++)
    {
        a[i] = a[i] - b[i];
        if(a[i] < 0)
        {
            a[i] += 10;
            a[i+1]--;
        }
    }
    i = len1 - 1;
    while(a[i] == 0)
    {
        i--;
    }
    
//    cout<<n1<<‘-‘<<n2<<"=";
    
    //判断正负号 
    if(c[0] == c[1])
    {
        if(c[0] == +)        //正相同 
        {
            int m = judgebig(n1, n2);
//            cout<<m<<endl;
            if(m == 2)        //n2>n1 
            {
                cout<<"-";
            }
        }
        else if(c[0] == -)    //负相同,将n1-n2变成,n2-n1; 
        {
            return toSub(n2, n1);
        }
    } 
    if(c[0] != c[1])
    {
        //进入加运算 
        if(c[0] == -)
        {
            int m = judgebig(n1, n2);
            if(m == 1)
            {
                cout<<-;
            }
        }
    }
    
    for(;i >= 0; i--)
    {
        cout<<a[i];
    }
    return 0;
}

//
void toMul(char n1[N], char n2[N])
{
    char temp[N];
    int a[N],b[N],k[N] = {0};    //注意这里数组k是存储结果,不要顺手用全局数组c 
    int i,j,h;
    int len1,len2;
    if( strlen(n1)<strlen(n2) )
    {
        strcpy(temp,n1);
        strcpy(n1,n2);
        strcpy(n2,temp);
    }
    
    len1=strlen(n1);
    len2=strlen(n2);
//    memset(c,0,sizeof(c)); //将数组c全换成0
    
    for(i=len1-1,j=0;i>=0;i--,j++)    //存储n1为整型数组a 
    {
        a[j]=n1[i]-0;
    }
    for(i=len2-1,j=0;i>=0;i--,j++)    //存储n2为整型数组b 
    {
        b[j]=n2[i]-0;
    }
    
    /*
    从第一个数开始,依次乘以第二个数的每一位,超过10进位 
    */ 
    for(i=0;i<len2;i++)
    {
        for(j=0;j<len1;j++)
        {
            k[i+j]=a[j]*b[i]+k[i+j];
        }
    }
    for(i=0;i<2*len1;i++)    
    {
        if(k[i]>=10)    //超过10进位 
        {
            k[i+1]=k[i+1]+k[i]/10;
            k[i]=k[i]%10;
        }
    }
    
    
    i=2*len1;
    while(k[i]==0)
    {
        i--;
    }
    
    //判断正负号
    if(c[0] != c[1])
    {
        cout<<-;
    }
     
    if(i<0)
    {
        cout<<"0"<<endl;
    }
    else
    {
        for(;i>=0;i--)
               cout<<k[i];
    } 
}

//
void toDiv(char n1[N], char n2[N])
{
    int i,p;
    int len1,len2;
    int result[N];

    len1=strlen(n1);
    len2=strlen(n2);
    if(len1<len2||(len1==len2&&strncmp(n1,n2,len2)<0))   //如果n1<n2,除法运算直接输出0
    {
        cout<<"0"<<endl; 
    }
    p=0;
    while(1)
    {
        result[p]=0;
        //要比较两数的大小 
        while(strncmp(n1,n2,len2)>=0)       //一直进行减法,直到不能减为止
         {
            sub(n1, n2, len1, len2);
            result[p]++;
        }
        p++;
        if(len1==len2)
            break;
        for(i=len2-1;i>=0;i--)             //在n2前面补0,以便进行减法运算
         {
            n2[i+1]=n2[i];
        }
        n2[0]=0;
        len2++;
        n2[len2]=\0;
    }
    i=0;
    while(1)
    {
        if(result[i]==0)
            i++;
        else
            break;
    }
    
    //判断正负号 
    if(c[0] != c[1])
    {
        cout<<-;
    }
    
    for(;i<p;i++)
        cout<<result[i];
}


//加等于 
char Add(char n1[N], char n2[N])
{
    return toAdd(n1, n2);
}

//减等于 
char Sub(char n1[N], char n2[N])
{
    return toSub(n1, n2);
}

//乘等于 
void Mul(char n1[N], char n2[N])
{
    toMul(n1, n2);
}

//除等于 
void Div(char n1[N], char n2[N])        //有问题,除等于情况输出为零 
{
    toDiv(n1, n2);
}

int main(void)
{
    while(1)
    {
        char num1[N], num2[N], result[N], i = 0, j;
        char n1[N], n2[N];                        
        cout<<"请输入第一个运算数:"<<endl;
        cin>>num1;
        
        cout<<"请输入第二个运算数:"<<endl;
        cin>>num2; 
        
        //去掉正负号存入n1 
        if(num1[0] == -)
        {
            i++;
            c[0] = num1[0];
            while(i<N)
            {
                n1[i-1] = num1[i];
                i++;
            }
        }
        else
        {
            c[0] = +;
            while(i<N)
            {
                n1[i] = num1[i];
                i++;
            }
        }
        
        //去掉正负号存入n2 
        if(num2[0] == -)
        {
            i = 1;
            c[1] = num2[0];
            while(i<N)
            {
                n2[i-1] = num2[i];
                i++;
            }
        }
        else
        {
            i = 0;
            c[1] = +;
            while(i<N)
            {
                n2[i] = num2[i];
                i++;
            } 
        }
//        cout<<n1<<‘ ‘<<n2<<endl;
        
        cout<<"请输入数字:1.+ 2.- 3.* 4./ 5.+= 6.-= 7.*= 8./="<<endl; 
        int q;
        cin>>q;
        switch(q)
        {
            case 1:
                cout<<"加运算:"<<endl;
                toAdd(n1, n2);
                break;
                
            case 2:
                cout<<endl;
                cout<<"减运算:"<<endl;
                toSub(n1, n2);
                break;
                
            case 3:
                cout<<endl; 
                cout<<"乘运算:"<<endl;
                toMul(n1, n2);
                break;
                
            case 4:
                cout<<endl;
                cout<<"除运算:"<<endl;
                toDiv(n1, n2);
                break;
                
            case 5:    
                cout<<endl;
                cout<<"加等于运算:"<<endl;
                Add(n1, n2);cout<<endl; 
                break;
                
            case 6:    
                cout<<"减等于运算:"<<endl;
                Sub(n1, n2);cout<<endl;
                break; 
            case 7:    
                cout<<"乘等于运算:"<<endl;             
                Mul(n1, n2);cout<<endl; 
                break;
            case 8:    
                cout<<"除等于运算:"<<endl;
                Div(n1, n2);cout<<endl; 
                break;
//            case 9:
//                cout<<"加运算:"<<endl;
//                toAdd(n1, n2);
//                cout<<endl;
//                cout<<"减运算:"<<endl;
//                toSub(n1, n2);
//                cout<<endl; 
//                cout<<"乘运算:"<<endl;
//                toMul(n1, n2);
//                cout<<endl;
//                cout<<"除运算:"<<endl;
//                toDiv(n1, n2);
//                cout<<endl;
//                cout<<"加等于运算:"<<endl;
//                Add(n1, n2);cout<<endl; 
//                cout<<"减等于运算:"<<endl;
//                Sub(n1, n2);cout<<endl;
//                cout<<"乘等于运算:"<<endl;            //有问题 
//                Mul(n1, n2);cout<<endl; 
//                cout<<"除等于运算:"<<endl;
//                Div(n1, n2);cout<<endl; 
//                break;
            default: 
                cout<<"输入出错!请重新输入:"<<endl;
                break;
        }
        cout<<endl<<endl;
    }

    return 0;
}


/*
int a[100];
整数数组不能用cout<<a输出,char a[100]可以那样输出 

要考虑到数组的范围,今天定义了1000大小的数组,反应很慢,误认为是程序出错,定义成100 就好了 
*/
View Code

 (太烂不敢露脸,,,*-*)

 

和同学的同学A的代码一比较,感觉自己很菜。下面是A的代码:

//#include "stdafx.h"
#include <string>
#include <iostream>
//#ifndef _DOUBLELONG_H_
#define _DOUBLELONG_H_
//#include "doublelong.h"
using namespace std;
class doublelong
{
public:
    doublelong();
    doublelong(const string num);
    friend istream& operator >> (istream& is, doublelong& num);
    friend ostream& operator << (ostream& os, doublelong& num);

    string add(string, string);//高精度整数加法
    string subtract(string, string);//高精度整数减法
    string multiply(string, string);//高精度整数乘法
    string divide(string, string);//高精度整数除法

    doublelong& operator = (doublelong& num);
    doublelong operator + (doublelong& num);
    doublelong operator - (doublelong& num);
    doublelong operator * (doublelong& num);
    doublelong operator / (doublelong& num);
    doublelong& operator += (doublelong& num);
    doublelong& operator -= (doublelong& num);
    doublelong& operator *= (doublelong& num);
    doublelong& operator /= (doublelong& num);
    ~doublelong();
private:
    string number;
};
/*#endif*/ // !_DOUBLELONG_H_
string doublelong::add(string num1, string num2)//高精度整数加法
{
    if (num1[0] == -&&isdigit(num2[0]))//第一个数是负数
    {
        num1.erase(0, 1);//去掉第一个数的负号
        return subtract(num2, num1);//变成减法
    }
    else if (isdigit(num1[0]) && num2[0] == -)//第二个数是负数
    {
        num2.erase(0, 1);//去掉第二个数的负号
        return subtract(num1, num2);//变成减法
    }
    else if (num1[0] == -&&num2[0] == -)//两个都是负数
    {
        num1.erase(0, 1);//去掉负号
        num2.erase(0, 1);//去掉负号
        return - + add(num1, num2);//相加后加上负号
    }
    string result = "";//存放结果
    int l1 = num1.size(), l2 = num2.size();
    if (l1>l2)//交换位置,把长度短的放在前面
    {
        string temp=num1;
        num1 = num2;
        num2 = temp;
        l1 = num1.size();
        l2 = num2.size();
    }
    int up = 0, n;
    while (l1>0)//遍历长度短的
    {
        n = (num1[l1 - 1] - 0) + (num2[l2 - 1] - 0) + up;//当前位相加,加上进位
        result = char(n % 10 + 0) + result;//模10
        up = n / 10;//计算进位
        l1--;
        l2--;
    }
    int l3 = num2.size() - num1.size() - 1;
    while (l3 >= 0)//计算剩下的部分
    {
        n = num2[l3] - 0 + up;//当前位加上进位
        result = char(n % 10 + 0) + result;//模10
        up = n / 10;//计算进位
        l3--;
    }
    if (up>0)
        result = 1 + result;
    return result;
}

string doublelong::subtract(string num1, string num2)//高精度整数减法
{
    if (num1 == num2)//相等返回 0
        return "0";
    if (num1[0] == -&&isdigit(num2[0]))//第一个数是负数
    {
        num1.erase(0, 1);
        return - + add(num1, num2);
    }
    else if (isdigit(num1[0]) && num2[0] == -)//第二个数是负数
    {
        num2.erase(0, 1);
        return add(num1, num2);
    }
    else if (num1[0] == -&&num2[0] == -)//两个都输负数
    {
        if (num1 == num2)
            return "0";
        num1.erase(0, 1);
        num2.erase(0,1);
        string temp = subtract(num1, num2);
        if (temp[0] == -)
        {
            temp.erase(0, 1);
            return temp;
        }
        else
            return - + temp;
    }
    string result = "", temp1 = num1, temp2 = num2;
    int l1 = num1.size(), l2 = num2.size();
    if (l1<l2)//短的放在后面
    {
        string temp=num1;
        num1 = num2;
        num2 = temp;
        l1 = num1.size();
        l2 = num2.size();
    }
    if (l1 == l2)//长度相等
    {
        if (num1<num2)//第一个数比第二个数小
            return - + subtract(num2, num1);
        int down = 0, n, n1, n2;
        while (l1>0)
        {
            n1 = num1[l1 - 1] - 0;
            n2 = num2[l2 - 1] - 0;
            if (n1 >= n2 + down)
            {
                n = n1 - n2 - down;//当前位相减,减去进位
                if (l1 == 1 && n == 0)
                    break;
                result = char(n + 0) + result;
                down = 0;
            }
            else
            {
                n = 10 + n1 - n2 - down;//当前位加上10,相减,再减去进位
                result = char(n + 0) + result;
                down = 1;
            }
            l1--;
            l2--;
        }
        int i;
        for (i = 0; i<result.length() && result[i] == 0; i++);
        result.erase(0, i);//去掉开头的0
    }
    else
    {
        int down = 0, n, n1, n2;
        while (l2>0)
        {
            n1 = num1[l1 - 1] - 0;
            n2 = num2[l2 - 1] - 0;
            if (n1 >= n2 + down)
            {
                n = n1 - n2 - down;//当前位相减,减去进位
                result = char(n + 0) + result;
                down = 0;
            }
            else
            {
                n = 10 + n1 - n2 - down;//当前位加上10,相减,再减去进位
                result = char(n + 0) + result;
                down = 1;
            }
            l1--;
            l2--;
        }
        int l3 = num1.size() - num2.size() - 1;//计算剩下的部分
        while (l3 >= 0)
        {
            n1 = num1[l3] - 0;
            if (l3 == 0 && n1 == down)
                break;
            if (n1 >= down)
            {
                n = num1[l3] - 0 - down;
                result = char(n + 0) + result;
                down = 0;
            }
            else
            {
                n = 10 + (num1[l3] - 0) - down;
                result = char(n + 0) + result;
                down = 1;
            }
            l3--;
        }
    }
    if (temp1.size()<temp2.size())
        result = - + result;
    return result;
}

string doublelong::multiply(string num1, string num2)//高精度整数乘法
{
    if (num1[0] == -&&isdigit(num2[0]))//第一个数是负数
    {
        num1.erase(0, 1);//去掉第一个数的负号
        string temp = multiply(num1, num2);
        if (temp == "0")
            return temp;
        else
            return - + temp;
    }
    else if (isdigit(num1[0]) && num2[0] == -)//第二个数是负数
    {
        num2.erase(0, 1);//去掉第二个数的负号
        string temp = multiply(num1, num2);
        if (temp == "0")
            return temp;
        else
            return - + temp;
    }
    else if (num1[0] == -&&num2[0] == -)//两个都是负数
    {
        num1.erase(0, 1);//去掉负号
        num2.erase(0, 1);//去掉负号
        return multiply(num1, num2);
    }
    int l1 = num1.length(), l2 = num2.length();
    int *n = new int[l1 + l2];//临时数组,存放乘法结果
    int i, j;
    for (i = 0; i<l1+l2; i++)//初始化数组
        n[i] = 0;
    for (i = 0; i<l1; i++)
        for (j = 0; j<l2; j++)
            n[i + j] += (num1[l1-1-i]-0) * (num2[l2-1-j]-0);//第 i+j 位的结果与第一个数的第i位和第二个数的第j位有关
    for (i = 0; i< l1 + l2 - 2; i++)
        if (n[i] >= 10)
        {
            n[i + 1] += n[i] / 10;//高一位加上当前位除以10
            n[i] %= 10;//当前位模10
        }
    while (n[i] >= 10)
    {
        n[i + 1] = n[i] / 10;
        n[i] %= 10;
        i++;
    }
    string result;
    for (; i >= 0; i--)
        result += char(n[i] + 0);//结果反向
    delete[] n;
    return result;
}

string doublelong::divide(string num1, string num2)//高精度整数除法
{
    if (num1[0] == -&&isdigit(num2[0]))//第一个数是负数
    {
        num1.erase(0, 1);//去掉第一个数的负号
        string temp = divide(num1, num2);
        if (temp == "0")
            return temp;
        else
            return - + temp;
    }
    else if (isdigit(num1[0]) && num2[0] == -)//第二个数是负数
    {
        num2.erase(0, 1);//去掉第二个数的负号
        string temp = divide(num1, num2);
        if (temp == "0")
            return temp;
        else
            return - + temp;
    }
    else if (num1[0] == -&&num2[0] == -)//两个都是负数
    {
        num1.erase(0, 1);//去掉负号
        num2.erase(0, 1);//去掉负号
        return divide(num1, num2);
    }

    int l1 = num1.length(), l2=num2.length(),i,n;
    if (l1 < l2)
        return "0";
    if (l1 == l2&&num1 < num2)
        return "0";
    string result,temp=num1.substr(0,l2-1),t;
    for (i = l2 - 1; i < l1; i++)//从除数的长度开始,到被除数的长度
    {
        n = 0;
        if (temp != "0")
            temp += num1[i];
        else
            temp = num1[i];
        t = subtract(temp, num2);
        while (t[0] != -)//不停的减去除数,直到小于0
        {
            n++;//商加一
            temp = t;
            t = subtract(temp, num2);
        }
        result += 0+n;
    }
    for (i = 0; i < result.length() && result[i] == 0; i++);
    result.erase(0, i);//去掉开头的0
    return result;
}

doublelong::doublelong()
{
    number = "0";
}

doublelong::doublelong(const string num)
{
    number = num;
}

istream& operator >> (istream& is, doublelong& num)
{
    is >> num.number;
    return is;
}

ostream& operator << (ostream& os, doublelong& num)
{
    os << num.number;
    return os;
}

doublelong& doublelong::operator = (doublelong& num)
{
    number = num.number;
    return *this;
}

doublelong doublelong::operator + (doublelong& num)
{
    doublelong temp;
    temp.number = add(number, num.number);
    return temp;
}

doublelong doublelong::operator - (doublelong& num)
{
    doublelong temp;
    temp.number = subtract(number, num.number);
    return temp;
}

doublelong doublelong::operator * (doublelong& num)
{
    doublelong temp;
    temp.number = multiply(number, num.number);
    return temp;
}

doublelong doublelong::operator / (doublelong& num)
{
    doublelong temp;
    temp.number = divide(number, num.number);
    return temp;
}

doublelong& doublelong::operator += (doublelong& num)
{
    number = add(number, num.number);
    return *this;
}
doublelong& doublelong::operator -= (doublelong& num)
{
    number = subtract(number, num.number);
    return *this;
}
doublelong& doublelong::operator *= (doublelong& num)
{
    number = multiply(number, num.number);
    return *this;
}
doublelong& doublelong::operator /= (doublelong& num)
{
    number = divide(number, num.number);
    return *this;
}

doublelong::~doublelong()
{
}




//int _tmain(int argc, _TCHAR* argv[])
int main(void) 
{
    while (1)
    {
        doublelong num1, num2;
        cin >> num1 >> num2;
        //cout << num1 << endl;
        //cout << num2 << endl;
        cout << num1 + num2 << endl;
        cout << num1 - num2 << endl;
        cout << num1 * num2 << endl;
        cout << num1 / num2 << endl;
        num1 += num2;
        cout << num1 << endl;
        num1 -= num2;
        cout << num1 << endl;
        num1 *= num2;
        cout << num1 << endl;
        num1 /= num2;
        cout << num1 << endl;
        //cout << (num1 += num2) << endl;
    }
    return 0;
}

(此代码为原作者所有,如有侵权,立删!)

 

20170104更新,完

大整数四则运算

标签:行存储   and   导出   define   ros   cas   int   strncmp   com   

原文地址:http://www.cnblogs.com/libra-yong/p/6240707.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!