大整数四则运算

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

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

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

定义并实现超长整数类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 就好了
*/

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

和同学的同学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更新,完

时间: 2024-10-08 23:35:22

大整数四则运算的相关文章

大整数四则运算(vector)

目录 基础 1. 高精度加法 2. 高精度减法 3. 高精度乘低精度 4. 高精度除以低精度 5. 高精度乘高精度 6. 高精度除以高精度 综合 总结 每逢大整数四则运算,都会怯懦,虽是算法竞赛必会的东西,也零散的学过,简单的总结过,但不成体系的东西心里一直没底. 所以今天消耗了大量的卡路里,啃了几套模板之后终于总结成了一套自己的模板 再也不用担心大整数啦 基础 1. 高精度加法 高精度加法等同于算术加法,做单个的加法运算之后存下进位 A和B都为正整数 vector中下标为0存的是低位(以下都是

7.2 大整数四则运算

7-2 BigInt1.c 1 #include <stdio.h> 2 #include <string.h> 3 typedef struct bigint 4 { 5 char *num; //指向长整数数组(序号0中保存着最低位) 6 char minus; //符号(1表示正数,-1表示负数) 7 int digit; //保存该数的位数(实际位数) 8 }BIGINT, *pBIGINT; 9 void BigIntTrans(pBIGINT num); //字符串转数

【面试】大整数四则运算

面试手写代码,当时只写出了加减乘,还写的漏洞百出.下面是加减法: 1 #include<iostream> 2 using namespace std; 3 4 struct BigN { 5 int data[1000]; //设最长1000位,数组的每个数字代表一位,data[0]存最低位 6 int len; 7 int sign;//0为负,1为正 8 BigN() { 9 memset(data, 0, sizeof(data)); 10 len = 0; 11 sign = 1;

模板 高精度大整数

#include<bits/stdc++.h> #define clr(x,y) memset((x),(y),sizeof(x)) using namespace std; typedef long long LL; const int MaxL=400; //大数长度 //大整数 //减法只能大减小 struct bign { int len, s[MaxL]; //构造函数 bign () { memset(s, 0, sizeof(s)); len = 1; } bign (int n

大整数的存储与加减乘除四则运算

当需要计算的整数或计算结果可能会超出long long 所能表示的范围时,应该用大整数来存储和计算(Java里面有BigInteger来存储大整数,这里讨论的是C++语言). 大整数的存储形式是下面这个结构体(包含了构造函数): // 大整数结构体 struct bign{ int d[1000]; int len; bign(){ memset(d, 0, sizeof(d)); len = 0; } }; 首先以字符串的形式读去数据,然后将字符串逐个逆序字符存入d[]数组(可以采用用reve

大整数类

大整数类又叫高精度. 就是求大数的四则运算的算法, (其实就是模拟小学生算数的方法, 什么? 你不会, 那你还不如小学生, 哈哈!). 在这里只贴加法运算符的重载,其他的运算符与加法类似.闲言少叙, 直接上代码(小声告诉你, 里面用了几个库函数和STL, 嘿嘿!!!). 1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<iostream> 5 using namespac

大整数的加减乘除

多项式的加减乘除能够利用多项式的加减乘除进行运算,所以下面程序採用了多项式的加减乘除.多项式运算已经在<算法导论>第30章有简要的介绍,详细的请參考数学书. 大整数加法:(利用书上公式轻松得出) //多项式加法-大数加法 #include <iostream> #include <time.h> using namespace std; #define m1 4 #define m2 5 //a[0]=x^0 a[1]=x^1....a[n]=x^n的关于x的多项式系数

大整数类BIGN的设计与实现 C++高精度模板

首先感谢刘汝佳所著的<算法竞赛入门经典>. 众所周知,C++中储存能力最大的unsigned long long 也是有着一个上限,如果我们想计算非常大的整数时,就不知所措了,所以,我写了一个高精度类,允许大整数的四则运算 这个类利用字符串进行输入输出,并利用数组进行储存与处理,通过模拟四则运算,可以计算很大的整数的加减乘除比大小. 贴上我的代码: #include<string> #include<iostream> #include<iosfwd> #i

大整数运算C++1

//下面的代码勉强算是bignum_beta1版本! //实现了大整数的加减乘除四则运算,以及求两个整数的最大公约数,以及求乘法逆,miller_rabin素性检验,平方_乘法算法 //不足之处,位数还很难扩展至几千位,以及运算速度有一点慢,既然是beta1,说明bug还是挺多的 //程序缺少测试数据来测试,所以有的结果不敢保证其正确性 //由于使用c++复写了很多运算符,加入这个文件之后,大数bignum可以看做是一个如同如同int一样的基本类型 //可以像int一样加减乘除和输入输出 #in