用的是最基本的算法——模拟笔算。先实现无符号的加减法两个私有函数,再重载+=、-=操作符,最后用+=、-=分别实现+、-操作。如果先实现+、-,再用+、-实现+=、-=,则+=、-=需要多赋值一次,不如前面的方案好。

++、--操作符分前缀和后缀,为了可以区分重载,后缀++、--的参数列表不为空,而是用一个int来使得参数列表非空,这个参数没有名字,也即仅起到区分作用,函数中不会使用这个参数。前缀++、--返回当前值的引用,后缀++、--返回原值。因此前缀++、--会高效一点。但是这个两个操作符的重载都是用的基本加减法实现,不会比+1、-1高效多少。

//unsigned +=
void BigInt::plus(const string& rval)
{
    if(num.size() < rval.size())
        num.insert(1, rval.size() - num.size(), '0');
    string::size_type i = num.size() - 1;
    string::size_type j = rval.size() - 1;
    while(j > 1){
        num[i] += rval[j--] - '0';
        if(num[i] > '9'){
            num[i] -= 10;
            ++num[i-1];
        }
        --i;
    }
    num[i] += rval[1] - '0';
    while(i > 1 && num[i] > '9'){
        num[i] -= 10;
        ++num[--i];
    }
    if(num[1] > '9'){
        num[1] -= 10;
        num.insert(1, 1, '1');
    }
}

//unsigned -=
void BigInt::minus(const string& rval)
{
    string::size_type i = num.size() - 1;
    for(string::size_type j = rval.size() - 1; j > 0; --j, --i){
        num[i] -= rval[j] - '0';
        if(num[i] < '0'){
            num[i] += 10;
            --num[i-1];
        }
    }
    while(i > 1 && num[i] < '0'){
        num[i] += 10;
        --num[--i];
    }
    i = 1;
    for(; i < num.size() - 1 && num[i] == '0'; ++i);
    if(i > 1)
        num.erase(1, i-1);
}
BigInt& BigInt::operator +=(const BigInt &rval)
{
    if(num[0] == rval.num[0])
        plus(rval.num);
    else {
        if(equal(rval.num)){
            num = "+0";
        } else if(smaller(rval.num)){
            string temp = num;
            num = rval.num;
            minus(temp);
        } else 
            minus(rval.num);
    }
    return *this;
}

BigInt& BigInt::operator -=(const BigInt &rval)
{
    if(num[0] == rval.num[0]){
        if(equal(rval.num)){
            num = "+0";
        } else if(smaller(rval.num)){
            string temp = num;
            num = rval.num;
            minus(temp);
            if(num[0] == '+')
                num[0] = '-';
            else
                num[0] = '+';
        } else 
            minus(rval.num);
    } else {
        plus(rval.num);
    }
    return *this;
}
BigInt operator+(const BigInt& lval, const BigInt& rval)
{
    BigInt sum(lval);
    sum += rval;
    return sum;
}

BigInt operator-(const BigInt& lval, const BigInt& rval)
{
    BigInt diff(lval);
    diff -= rval;
    return diff;
}
//prefix increment
BigInt& BigInt::operator ++()
{
    string::size_type i = num.size() - 1;
    if(num[0] == '+'){
        ++num[i];
        while(i > 1 && num[i] > '9'){
            num[i] -= 10;
            ++num[--i];
        }
        if(num[1] > '9'){
            num[1] -= 10;
            num.insert(1, 1, '1');
        }
    } else {
        --num[i];
        while(i > 1 && num[i] < '0'){
            num[i] += 10;
            --num[--i];
        }
        i = 1;
        for(; i < num.size() - 1 && num[i] == '0'; ++i);
        if(i > 1)
            num.erase(1, i-1);
        if(num[1] == '0')
            num[0] = '+';
    }
    return *this;
}
//prefix decrement
BigInt& BigInt::operator --()
{
    string::size_type i = num.size() - 1;
    if(num[0] == '+'){
        if(num[1] == '0')
            num = "-1";
        else {
            --num[i];
            while(i > 1 && num[i] < '0'){
                num[i] += 10;
                --num[--i];
            }
            i = 1;
            for(; i < num.size() - 1 && num[i] == '0'; ++i);
            if(i > 1)
                num.erase(1, i-1);
        }
    } else {
        ++num[i];
        while(i > 1 && num[i] > '9'){
            num[i] -= 10;
            ++num[--i];
        }
        if(num[1] > '9'){
            num[1] -= 10;
            num.insert(1, 1, '1');
        }
    }
    return *this;
}
//postfix increment
BigInt BigInt::operator ++(int)
{
    BigInt temp(*this);
    ++*this;
    return temp;
}
//postfix decrement
BigInt BigInt::operator --(int)
{
    BigInt temp(*this);
    --*this;
    return temp;
}