【C++】C++大数之运算符重载

来源:互联网 发布:淘宝多少天自动付款 编辑:程序博客网 时间:2024/05/21 10:20

一、实验项目内容

Modify the “HugeInteger” Class. The new class should also provide the following overloaded operator capabilities:

. Overload the addition operator (+), the subtraction operator (-), the multiplication operator (*) and the division operator (/).. Overload output operator (<<).. Overload all the relational and equality operators.

You can use the following code to test your class design.

// HugeInt test program.#include <iostream>#include "Hugeint.h"using namespace std;int main(){   HugeInt n1( 7654321 );   HugeInt n2( 7891234 );   HugeInt n3( "99999999999999999999999999999" );   HugeInt n4( "1" );   HugeInt n5;   cout << "n1 is " << n1 << "\nn2 is " << n2      << "\nn3 is " << n3 << "\nn4 is " << n4      << "\nn5 is " << n5 << "\n\n";   n5 = n1 + n2;   cout << n1 << " + " << n2 << " = " << n5 << "\n\n";   cout << n3 << " + " << n4 << "\n= " << ( n3 + n4 ) << "\n\n";   n5 = n1 + 9;   cout << n1 << " + " << 9 << " = " << n5 << "\n\n";   n5 = n2 + "10000";   cout << n2 << " + " << "10000" << " = " << n5 << endl;}

二、实验过程或算法

HugeInteger.h:

#ifndef HUGEINTER_H#define HUGEINTER_H#include <iostream>#include <algorithm>#include <string.h>using namespace std;class HugeInteger{private:    string hugeInteger;                                  //声明私有成员hugeIntegerpublic:    HugeInteger();                                       //default构造函数    HugeInteger( string HugeInteger1);                    //构造函数1    HugeInteger( int HugeInteger1);                       //构造函数2    string getHugeInteger();                              //getting    void setHugeInteger(const string& hugeInteger);       //setting    //重载<<    friend ostream& operator<<(ostream& output, const HugeInteger& aHugeInter) ;    //重载+    friend HugeInteger operator +(const HugeInteger& aHugeInteger, const HugeInteger& bHugeInteger);    friend HugeInteger operator +(const HugeInteger& aHugeInteger, const string s);    friend HugeInteger operator +(const HugeInteger& aHugeInteger, const int i);    //重载-    friend HugeInteger operator -(const HugeInteger& aHugeInteger, const HugeInteger& bHugeInteger);    friend HugeInteger operator -(const HugeInteger& aHugeInteger, const string s);    friend HugeInteger operator -(const HugeInteger& aHugeInteger, const int i);    //重载*    friend HugeInteger operator *(const HugeInteger& aHugeInteger,const HugeInteger& bHugeInteger);    friend HugeInteger operator *(const HugeInteger& aHugeInteger,const string s);    friend HugeInteger operator *(const HugeInteger& aHugeInteger, const int i);    //重载/    friend HugeInteger operator /(const HugeInteger& aHugeInteger,            const HugeInteger& bHugeInteger);    friend HugeInteger operator /(const HugeInteger& aHugeInteger,            const string s);    friend HugeInteger operator /(const HugeInteger& aHugeInteger, const int i);};#endif

HugeInteger.cpp:

#include "HugeInteger.h"#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>using namespace std;HugeInteger::HugeInteger(){    this->hugeInteger="null";}HugeInteger:: HugeInteger( string HugeInteger1){    this->hugeInteger=HugeInteger1;}HugeInteger:: HugeInteger( int HugeInteger1){    char t[256];    sprintf(t, "%d", HugeInteger1);    this->hugeInteger=t;}string HugeInteger::getHugeInteger() {        return hugeInteger;    }void HugeInteger:: setHugeInteger(const string& hugeInteger) {        this->hugeInteger = hugeInteger;    }//加法运算char* getAddNumber(char* HugeInteger1,char* HugeInteger2) {    int maxlen = max(strlen(HugeInteger1), strlen(HugeInteger2));    //多两个字符,一个是结束符'/0',另一个保存当两个数最高位相加后有进位的情况    char* p = new char[maxlen + 2];    //结束符    *(p + maxlen + 1) = '\0';    //声明两个指针分别指向HugeInteger1和HugeInteger2的末尾,不含结束符    char* pHugeInteger1 = HugeInteger1 + strlen(HugeInteger1) - 1;    char* pHugeInteger2 = HugeInteger2 + strlen(HugeInteger2) - 1;    int m = 0;    int n = 0;    //进位    int c = 0;    for (int i = maxlen; i > 0; i--) {        m = n = 0;        //因为当pHugeInteger1到达第一个字符时,即pHugeInteger1=a时,也要进行计算,所以这里用(pHugeInteger1-1)来判断        //'0'的Asic是48,减去48转成数字        if ((pHugeInteger1 + 1) != HugeInteger1) {            m = *pHugeInteger1 - 48;            pHugeInteger1--;        }        if ((pHugeInteger2 + 1) != HugeInteger2) {            n = *pHugeInteger2 - 48;            pHugeInteger2--;        }        //为p指针的第i个字符赋值        *(p + i) = (m + n + c) % 10 + 48;        //取得进位        c = (m + n + c) / 10;    }    *p = 48 + c;    if(*p=='0'){                        //如果结果的第一位是‘0’,表示没有进位        return p+1;                     //返回第二位的指针,以去除第一位多余的0    }    return p;}//减法运算char* getSubNumber(char* HugeInteger1,char* HugeInteger2){    int isNegative=0;                   //定义结果是否为负数的标志,初始为0,不是负数    int lHugeInteger1 = strlen(HugeInteger1), lHugeInteger2 = strlen(            HugeInteger2);    if (lHugeInteger1 > lHugeInteger2) { //HugeInteger1的位数大于HugeInteger2,则HugeInteger1大        isNegative=0;    } else if (lHugeInteger1 < lHugeInteger2) { //HugeInteger1的位数小于HugeInteger2,则HugeInteger1小        char* temp = HugeInteger1;        HugeInteger1 = HugeInteger2;        HugeInteger2 = temp;        isNegative=1;    } else {                                                  //位数相等        char* pHugeInteger1 = HugeInteger1;        char* pHugeInteger2 = HugeInteger2;        for (int c = 0; c < lHugeInteger1; c++) {                  //依次比较每一位数的大小            if ((*(pHugeInteger1+c)) > (*(pHugeInteger2+c))) {         //不等,则比较大小                isNegative=0;                break;            } else if ((*(pHugeInteger1+c)) <(*(pHugeInteger2+c))) {                char* temp = HugeInteger1;                HugeInteger1 = HugeInteger2;                HugeInteger2 = temp;                isNegative = 1;                break;            } else {                                          //相等继续                continue;            }        }    }    int maxlen = max(strlen(HugeInteger1), strlen(HugeInteger2));    //应为HugeInteger1始终大于HugeInteger2,不考虑被减数最高位不够减的情况    char* p = new char[maxlen + 1];    //最后一位是结束符    *(p + maxlen) = '\0';    //声明两个指针分别指向HugeInteger1和HugeInteger2的末尾,不包含结束符    char* pHugeInteger1 = HugeInteger1 + strlen(HugeInteger1) - 1;    char* pHugeInteger2 = HugeInteger2 + strlen(HugeInteger2) - 1;    int m = 0;    int n = 0;    //借位位    int c = 0;    for (int i = maxlen - 1; i >=0; i--) {        m = n = 0;        //'0'的Asic是48,减去48转成数字        if ((pHugeInteger1 + 1) != HugeInteger1) {            m = *pHugeInteger1 - 48;            pHugeInteger1--;        }        if ((pHugeInteger2 + 1) != HugeInteger2) {            n = *pHugeInteger2 - 48;            pHugeInteger2--;        }        //不够减,要借位        if (m < n) {            //为p指针的第i个字符赋值            *(p + i) = 10 + m - n - c + 48;            c = 1;        } else {            //虽然够减,但是如果再算是借走的一位,那么就小于0了            if (m - n - c < 0)                *(p + i) = 10 + m - n - c + 48;            else {                *(p + i) = m - n - c + 48;                c = 0;            }        }    }    if (isNegative == 1) {        if (*p == '0') {                        //如果结果的第一位是‘0’,表示没有进位            char* temp = new char[maxlen];            temp = p + 1;                            //返回第二位的指针,以去除第一位多余的0            char* newp = new char[maxlen + 1];            *newp = '-';                             //首地址带符号‘-’            for (int i = 0; i < maxlen; i++) {                *(newp + 1 + i) = *(temp+i);            }            return newp;                          //返回带符号的新字符串        }        else {            char* temp2 = new char[maxlen+1];            temp2 = p ;            char* newp2 = new char[maxlen +2];            *newp2 = '-';                             //首地址带符号‘-’            for (int i = 0; i < maxlen+1; i++) {                *(newp2 + 1 + i) = *(temp2+i);            }            return newp2;                          //返回带符号的新字符串        }    }    else {        if (*p == '0') {                        //如果结果的第一位是‘0’,表示没有进位            return p+1;                     //返回第二位的指针,以去除第一位多余的0        }        return p;    }}//乘法运算char* getMultNumber(char* a, char* b) {    int sizea = strlen(a);    int sizeb = strlen(b);    char* p = new char[sizea + sizeb + 1];//两数相乘所得的积的位数最大为两个数位数只和,多申请一位放'\0'    char* pA = a + sizea - 1;    char* pB = b + sizeb - 1;    int m = 0;    int n = 0;    //进位    int c = 0;//存放该位置原有的数    int s = 0;//记数    int i = 0;    int j = 0;//具体实现过程详见说明文件    for (i = 0; i < sizea; i++) {        m = *(pA - i) - 48;        c = 0;        for (j = 0; j < sizeb; j++) {            n = *(pB - j) - 48;//判断该位置原来是否为0            if ((*(p + i + j) >= '0') && (*(p + i + j) <= '9'))                s = *(p + i + j) - 48;            else                s = 0;            *(p + i + j) = (m * n + c + s) % 10 + 48;            c = (m * n + c + s) / 10;        }        *(p + i + j) = 48 + c;    }    if (c > 0)        *(p + i + j) = '\0';    else        *(p + i + j - 1) = '\0';    int size1 = strlen(p) - 1;    int size2 = (size1 + 1) / 2;    char temp;    for (int i = 0; i < size2; i++) {        temp = p[i];        p[i] = p[size1 - i];        p[size1 - i] = temp;    }    return p;}//除法运算(保留个位)string getDivNumber(const string &str1,const string &str2)  //  str1/str2{    int i;    int length,len1,len2,len,index;    bool flag;    len1=str1.length();    len2=str2.length();    length=len1-len2;    if(length<0) return "0";    int *num1=new int[len1+1];    int *num2=new int[len2+1];    int *quotient=new int[length+2];    memset(num1,0,sizeof(int)*(len1+1));    memset(num2,0,sizeof(int)*(len2+1));    memset(quotient,0,sizeof(int)*(length+2));    for(i=len1-1,index=0;i>=0;i--)    {        num1[index++]=str1[i]-'0';    }    for(i=len2-1,index=0;i>=0;i--)    {        num2[index++]=str2[i]-'0';    }    while(true)    {        for(i=len1-1;i>=0;i--)        {            if(num1[i])            {                len1=i+1;                break;            }            if(i==0) len1=0;        }        len=len1-len2;        if(len<0) break;        flag=false;        index=0;        for(i=len1-1;i>=len;i--)        {            if(num1[i]==num2[i-len]) continue;            else if(num1[i]<num2[i-len])            {                flag=true;                break;            }            else            {                break;            }        }        if(flag) --len;        if(len<0) break;        while(++index)        {            flag=false;            for(i=len1-1;i>=len;i--)            {                if(num1[i]==num2[i-len]) continue;                else if(num1[i]<num2[i-len])                {                    flag=true;                    break;                }                else                {                    break;                }            }            if(flag)            {                --index;                break;            }            for(i=len;i<len1;i++)            {                num1[i]-=num2[i-len];                if(num1[i]<0)                {                    num1[i]+=10;                    --num1[i+1];                }            }        }        if(index==0) break;        else quotient[len]=index;    }    string ans;    flag=false;    for(i=length;i>=0;i--)    {        if(flag||quotient[i])        {            flag=true;            ans+='0'+quotient[i];        }    }    if(!flag) ans="0";    delete [] num1;    delete [] num2;    delete [] quotient;    return ans;}//重载<<ostream& operator<<(ostream& output, const HugeInteger& aHugeInter) {    output << aHugeInter.hugeInteger;    return output;}//重载+HugeInteger operator +(const HugeInteger& aHugeInteger,        const HugeInteger& bHugeInteger) {    const char* a = aHugeInteger.hugeInteger.c_str();    //sting转换成char*    const char* b = bHugeInteger.hugeInteger.c_str();    return HugeInteger(getAddNumber((char*)a,(char*)b));}HugeInteger operator +(const HugeInteger& aHugeInteger, const string s){    const char* a = aHugeInteger.hugeInteger.c_str();    //sting转换成char*    const char* b = s.c_str();    return HugeInteger(getAddNumber((char*)a,(char*)b));}HugeInteger operator +(const HugeInteger& aHugeInteger, const int i){    char t[256];    sprintf(t, "%d", i);    string temp=t;    const char* a = aHugeInteger.hugeInteger.c_str();    //sting转换成char*    const char* b =temp.c_str();    return HugeInteger(getAddNumber((char*)a,(char*)b));}//重载-HugeInteger operator -(const HugeInteger& aHugeInteger,        const HugeInteger& bHugeInteger) {    const char* a = aHugeInteger.hugeInteger.c_str();    //sting转换成char*    const char* b = bHugeInteger.hugeInteger.c_str();    return HugeInteger(getSubNumber((char*)a,(char*)b));}HugeInteger operator -(const HugeInteger& aHugeInteger, const string s){    const char* a = aHugeInteger.hugeInteger.c_str();    //sting转换成char*    const char* b = s.c_str();    return HugeInteger(getSubNumber((char*)a,(char*)b));}HugeInteger operator -(const HugeInteger& aHugeInteger, const int i){    char t[256];    sprintf(t, "%d", i);    string temp=t;    const char* a = aHugeInteger.hugeInteger.c_str();    //sting转换成char*    const char* b =temp.c_str();    return HugeInteger(getSubNumber((char*)a,(char*)b));}//重载*HugeInteger operator *(const HugeInteger& aHugeInteger,        const HugeInteger& bHugeInteger) {    const char* a = aHugeInteger.hugeInteger.c_str();    //sting转换成char*    const char* b = bHugeInteger.hugeInteger.c_str();    return HugeInteger(getMultNumber((char*)a,(char*)b));}HugeInteger operator *(const HugeInteger& aHugeInteger, const string s){    const char* a = aHugeInteger.hugeInteger.c_str();    //sting转换成char*    const char* b = s.c_str();    return HugeInteger(getMultNumber((char*)a,(char*)b));}HugeInteger operator *(const HugeInteger& aHugeInteger, const int i){    char t[256];    sprintf(t, "%d", i);    string temp=t;    const char* a = aHugeInteger.hugeInteger.c_str();    //sting转换成char*    const char* b =temp.c_str();    return HugeInteger(getMultNumber((char*)a,(char*)b));}//重载/HugeInteger operator /(const HugeInteger& aHugeInteger,        const HugeInteger& bHugeInteger) {    return HugeInteger(getDivNumber(aHugeInteger.hugeInteger,bHugeInteger.hugeInteger));}HugeInteger operator /(const HugeInteger& aHugeInteger, const string s){    return HugeInteger(getDivNumber(aHugeInteger.hugeInteger,s));}HugeInteger operator /(const HugeInteger& aHugeInteger, const int i){    char t[256];    sprintf(t, "%d", i);    string temp=t;    return HugeInteger(getDivNumber(aHugeInteger.hugeInteger,temp));}

测试类:

#include <iostream>#include "HugeInteger.h"using namespace std;int main() {    HugeInteger n1(7654321);    HugeInteger n2(7891234);    HugeInteger n3("99999999999999999999999999999");    HugeInteger n4("1");    HugeInteger n5;    cout << "n1 is " << n1 << "\nn2 is " << n2 << "\nn3 is " << n3 << "\nn4 is "            << n4 << "\nn5 is " << n5 << "\n\n";    n5 = n1 + n2;    cout << n1 << " + " << n2 << " = " << n5 << "\n\n";    n5 = n1 - n2;              //小减大    cout << n1 << " - " << n2 << " = " << n5 << "\n\n";    n5 = n2- n1;               //大减小    cout << n2<< " - " << n1<< " = " << n5 << "\n\n";    n5 = n2 * n1;               //乘法    cout << n2 << " * " << n1 << " = " << n5 << "\n\n";    n5 = n2 / n1;               //除法  保留到整数    cout << n2 << " / " << n1 << " = " << n5 << "\n\n";    cout << n3 << " + " << n4 << "\n= " << (n3 + n4) << "\n\n";    n5 = n1 + 9;               //与int类型运算    cout << n1 << " + " << 9 << " = " << n5 << "\n\n";    n5 = n2 + "10000";         //与string类型运算    cout << n2 << " + " << "10000" << " = " << n5 << endl;    n5 = n2 * "10000";         //乘法运算    cout << n2 << " * " << "10000" << " = " << n5 << endl;    n2= n5 /"10000";         //除法运算    cout << n5<< " / " << "10000" << " = " << n2<< endl;    return 0;}

三、实验结果和截图