@TOC
仅供参考

题目

定义并实现超长整数类doublelong,要求如下:
64位数据长度,有符号
支持+、-、*、/运算
支持+=、-=、/=运算
支持cin>>和cout<<操作

设计思想

根据题意,创造一个超长整数类doublelong类。因为整数长度可能非常长,故使用指针创造动态数组的方式来存储数据,并用int型的length来表示其实际长度,用bool型的symbol来表示其符号。
对于构造函数重载,需要重载可以输入字符来转化的构造函数、可以将原本的long long型数据转化成doublelong类的构造函数,以及对于数组进行装载的构造函数。 而对于复制构造函数,因为该类中具有指针,故必须重载复制构造函数以达到深复制的目的。
接着重载+,-,*,/,+=,-=,*=,/=运算符。
对于+运算符,考虑到符号的不同,分为两种情况:同符号相加以及异号相加。对于同号相加,设置进位,直接将长度短的数字加到长度长的数字上。而对于异号相加,相当于减法,则设置借位,用长度长的数字减去长度短的数字。若碰到异号同长度的情况,则从最高位开始逐级判断其大小,最后用大的数字减去小的数字。
对于-运算符,将减数取反,即变成了加法,进行加运算即可。
对于*运算符,模拟手算乘法的过程,即将一个数与另一个数的每一位相乘,最后结果带位数相加。这里进行了简便算法,即先将每一位相乘,得到的结果再进行变换,最后形成数组中的每一位只有一个数字的状态。
对于/运算符,这里考虑减法计算,即先将除数扩大到与被除数相同位数,将两者相减,直到结果即将为负数时停止,然后除数退位,再减……以此类推,直到除数回到原来的位置为止。结果即为除数进位数与相减的次数之积的总和。
而对于+=,-=,*=,/=运算符,则将其拆开成例如a=a+b的形式直接计算。
再重载>>与<<运算符。因为两个运算符是在istream和ostream类中的,故无法直接重载。在此将两个重载设为友元函数后进行重载。
在该类中,还要考虑强制类型转换问题,因为在long long型的数字与doublelong型数字进行运算时,long long型应当先转化为doublelong型,再进行运算,而运算结果也应为doublelong型。
最后在主函数中对于10个运算符进行测试。

代码

doublelong.h

#pragma once
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
#ifndef _DOUBLELONG_H_
#define _DOUBLELONG_H_
class doublelong {
private:
    int* num;
    bool symbol;
    int length;
public:

    doublelong() {
        symbol = true;
        num = NULL;
        length = 0;
    }

    doublelong(string t) {
        num = new int[t.length()];
        if (t[0] != '-') {
            length = t.length();
            symbol = true;
            for (int i = t.length() - 1; i >= 0; i--) {
                num[t.length() - i - 1] = t[i] - '0';
            }
        }
        else {
            length = t.length() - 1;
            symbol = false;
            for (int i = t.length() - 1; i > 0; i--) {
                num[t.length() - i - 1] = t[i] - '0';
            }
        }
    }

    doublelong(long long t) {

        if (t >= 0) symbol = true;
        else {
            symbol = false;
            t = -t;
        }
        num = new int[100];
        if (t == 0) {
            num[0] = 0;
            length = 1;
            return;
        }
        int cnt = 0;
        while (t != 0) {
            num[cnt++] = t % 10;
            t /= 10;
        }
        
        length = cnt;

    }

    doublelong(int t[], int len, bool sym) {
        num = new int[len];
        length = len;
        for (int i = 0; i < len; i++)  num[i] = t[i];
        symbol = sym;
    }



    doublelong(const doublelong & t) {
        num = new int[t.length];
        length = t.length;
        for (int i = 0; i < length; i++) num[i] = t.num[i];
        symbol = t.symbol;
    }

    void operator = (long long x);


    doublelong operator + (doublelong & x);
    doublelong operator - (doublelong & x);
    doublelong operator * (doublelong & x);
    doublelong operator / (doublelong & x);
    doublelong& operator += (doublelong & x);
    doublelong& operator -= (doublelong & x);
    doublelong& operator *= (doublelong & x);
    doublelong& operator /= (doublelong & x);



    doublelong operator + (long long x);
    doublelong operator - (long long x);
    doublelong operator * (long long x);
    doublelong operator / (long long x);
    doublelong& operator += (long long x);
    doublelong& operator -= (long long x);
    doublelong& operator *= (long long x);
    doublelong& operator /= (long long x);

    friend istream& operator >> (istream & in, doublelong & x);
    friend ostream& operator << (ostream & out, doublelong & x);
};

void doublelong::operator = (long long t) {

    if (t >= 0) symbol = true;
    else {
        symbol = false;
        t = -t;
    }
    num = new int[100];
    if (t == 0) {
        num[0] = 0;
        length = 1;
        return;
    }
    int cnt = 0;
    while (t != 0) {
        num[cnt++] = t % 10;
        t /= 10;
    }
    
    length = cnt;

}



doublelong doublelong::operator + (doublelong & x) {
    int len = (length > x.length ? length : x.length) + 1;

    bool symj = symbol == x.symbol ? true : false;
    bool sym;
    int* t = new int[len];
    for (int i = 0; i < len; i++) t[i] = 0;
    int up = 0;
    if (symj) {
        sym = symbol;
        if (length > x.length) {
            for (int i = 0; i < length; i++) t[i] = num[i];
            for (int i = 0; i < x.length; i++) {
                t[i] += x.num[i] + up;
                up = t[i] / 10;
                t[i] = t[i] % 10;
            }
            t[x.length] += up;
            for (int i = x.length; i < length; i++)
                if (t[i] >= 10) {
                    t[i + 1]++;
                    t[i] = t[i] - 10;
                }
            if (t[length] == 0) len -= 1;
        }
        else {
            for (int i = 0; i < x.length; i++) t[i] = x.num[i];
            for (int i = 0; i < length; i++) {
                t[i] += num[i] + up;
                up = t[i] / 10;
                t[i] = t[i] % 10;
            }
            t[x.length] += up;
            for (int i = length; i < x.length; i++)
                if (t[i] >= 10) {
                    t[i + 1]++;
                    t[i] = t[i] - 10;
                }
            if (t[x.length] == 0) len -= 1;
        }
    }
    else {
        if (length > x.length) {
            sym = symbol;
            for (int i = 0; i < length; i++) t[i] = num[i];
            for (int i = 0; i < x.length; i++) {
                t[i] -= (up + x.num[i]);
                if (t[i] < 0) {
                    t[i] = 10 + t[i];
                    up = 1;
                }
                else up = 0;
            }
            t[x.length] -= up;
            for (int i = x.length; i < length; i++) {
                if (t[i] < 0) {
                    t[i + 1]--;
                    t[i] = 10 + t[i];
                }
            }

            if (t[len - 2] == 0) {
                len -= 2;
            }
            else len -= 1;

        }
        else if (length < x.length) {
            sym = x.symbol;
            for (int i = 0; i < x.length; i++) t[i] = x.num[i];
            for (int i = 0; i < length; i++) {
                t[i] -= (up + num[i]);
                if (t[i] < 0) {
                    t[i] = 10 + t[i];
                    up = 1;
                }
                else up = 0;
            }
            t[length] -= up;
            for (int i = length; i < x.length; i++) {
                if (t[i] < 0) {
                    t[i + 1]--;
                    t[i] = 10 + t[i];
                }
            }
            if (t[len - 2] == 0) {
                len -= 2;
            }
            else len -= 1;
        }
        else {
            int m = len - 2;
            while (num[m] == x.num[m]) m--;
            if (m < 0) {
                len = 1;
                t[0] = 0;
                sym = true;
            }
            else {
                len = m + 1;
                if (num[len - 1] > x.num[len - 1]) {
                    sym = symbol;
                    for (int i = 0; i < len; i++) t[i] = num[i];
                    for (int i = 0; i < len; i++) {
                        t[i] -= (up + x.num[i]);
                        if (t[i] < 0) {
                            t[i] = 10 + t[i];
                            up = 1;
                        }
                        else up = 0;
                    }
                    
                    t[len - 1] -= up;
                    if (t[len - 1] == 0) {
                        len -= 1;
                    }

                    
                }
                else {
                    sym = x.symbol;
                    for (int i = 0; i < x.length; i++) t[i] = x.num[i];
                    for (int i = 0; i < length; i++) {
                        t[i] -= (up + num[i]);
                        if (t[i] < 0) {
                            t[i] = 10 + t[i];
                            up = 1;
                        }
                        else up = 0;
                    }
                    t[len - 1] -= up;
                    if (t[len - 1] == 0) {
                        len -= 1;
                    }
                    
                }
            }
        }
    }
    return doublelong(t, len, sym);
}
doublelong doublelong::operator+(long long x) {
    doublelong t(x);
    return *this + t;
}
doublelong& doublelong::operator += (doublelong & x) {
    *this = *this + x;
    return *this;
}
doublelong& doublelong::operator += (long long x) {
    *this = *this + x;
    return *this;
}







doublelong doublelong::operator-(doublelong & x) {
    x.symbol = !x.symbol;
    doublelong y;
    y = *this + x;
    x.symbol = !x.symbol;
    return y;
}
doublelong doublelong::operator-(long long x) {
    doublelong t(x);
    return *this - t;
}
doublelong& doublelong::operator -= (doublelong & x) {
    *this = *this - x;
    return *this;
}
doublelong& doublelong::operator -= (long long x) {
    *this = *this - x;
    return *this;
}







doublelong doublelong::operator*(doublelong & x) {
    int* t = new int[length + x.length];
    for (int i = 0; i < length + x.length; i++) {
        t[i] = 0;
    }
    int len = 0;
    for (int i = 0; i < length; i++)
        for (int j = 0; j < x.length; j++) {
            t[i + j] += num[i] * x.num[j];
        }

    for (int i = 0; i < length + x.length - 1; i++) {
        t[i + 1] += t[i] / 10;
        t[i] = t[i] % 10;
    }


    for (int i = length + x.length - 1; i >= 0; i--)
        if (t[i] != 0) {
            len = i + 1;
            break;
        }
    bool sym = !(symbol ^ x.symbol);
    if (len == 0) len = 1;
    return doublelong(t, len, sym);
}
doublelong doublelong::operator*(long long x) {
    doublelong t(x);
    return *this* t;
}
doublelong& doublelong::operator *= (doublelong & x) {
    *this = *this * x;
    return *this;
}
doublelong& doublelong::operator *= (long long x) {
    *this = *this * x;
    return *this;
}







doublelong doublelong::operator/(doublelong & x) {

    if (x.length == 1 && x.num[0] == 0) {
        cout << "divide error!!!!!!!!!!!!!!" << endl;
        return 0;
    }

    doublelong ans = 0;

    if (length >= x.length) {
        doublelong t, th = *this;

        th.symbol = true;
        doublelong* pow = new doublelong[length - x.length + 1];
        pow[0] = 1;
        for (int i = 0; i < length - x.length; i++) pow[i + 1] = pow[i] * 10;//指数表
        for (int i = length - x.length; i >= 0; i--) {
            t = x * pow[i];

            t.symbol = true;
            while (1) {//这个最多进行9次
                doublelong y = th - t;
                if (!y.symbol) break;
                th = th - t;
                
                ans = ans + pow[i];
            
            }
        }
    }
    else ans = 0;
    ans.symbol = !(this->symbol ^ x.symbol);
    return ans;
}
doublelong doublelong::operator/(long long x) {
    doublelong y(x);
    return *this / y;
}
doublelong& doublelong::operator /= (doublelong & x) {
    *this = *this / x;
    return *this;
}
doublelong& doublelong::operator /= (long long x) {
    *this = *this / x;
    return *this;
}



istream& operator >>(istream & in, doublelong & x) {
    string s;
    in >> s;
    x = s;
    return in;
}

ostream& operator <<(ostream & out, doublelong & x) {
    if (!x.symbol&&!(x.num[0]==0&&x.length==1)) out << "-";
    for (int i = x.length - 1; i >= 0; i--) {
        out << x.num[i];
    }
    return out;
}

#endif // !_DOUBLELONG_H_

main函数

#include<cstdio>
#include"doublelong.h"
using namespace std;

int main() {
    doublelong x1, x2;
    doublelong y;
    cin >> x1 >> x2;
    y = x1 + x2;
    cout << "x1+x2:" << y << endl;
    y = x1 - x2;
    cout << "x1-x2:" << y << endl;
    y = x1 * x2;
    cout << "x1*x2:" << y << endl;  
    y = x1 / x2;
    cout << "x1/x2:" << y << endl;
    x1 += x2;
    cout << "x1+=x2:" << x1 << endl;
    x1 -= x2;
    cout << "x1-=x2:" << x1 << endl;
    x1 *= x2;
    cout << "x1*=x2:" << x1 << endl;
    x1 /= x2;
    cout << "x1/=x2:" << x1 << endl;
    
    return 0;

}