#include <iostream>
#include <list>
#include <string>
using namespace std;
class Bigint {
public:
static Bigint fromString(const string& strint);
string toString() const;
Bigint add(const Bigint& bigint) const;
Bigint subtract(const Bigint& bigint) const;
protected:
int sign;
list<int> digs;
Bigint(const int& sign, const list<int>& digs);
static list<int> pad(const list<int>& digs, const int& len);
static list<int> trim(const list<int>& digs);
static int compare(const list<int>& digs1, const list<int>& digs2);
static list<int> add(const list<int>& digs1, const list<int>& digs2);
static list<int> subtract(const list<int>& digs1, const list<int>& digs2);
};
Bigint Bigint::fromString(const string& strint) {
int sign = 1;
int i = 0;
if (strint[0] == '+') {
sign = 1;
i = 1;
}
else if (strint[0] == '-') {
sign = -1;
i = 1;
}
list<int> digs;
for (; i < strint.length(); i++) digs.push_back(int(strint[i] - '0'));
return Bigint(sign, digs);
}
string Bigint::toString() const {
string result = "";
if (this->sign < 0) result += '-';
for (list<int>::const_iterator iter = this->digs.begin(); iter != this->digs.end(); iter++)
result += '0' + *iter;
return result;
}
Bigint Bigint::add(const Bigint& bigint) const {
int sign;
list<int> digs;
list<int> digs1 = pad(this->digs, this->digs.size() < bigint.digs.size() ? bigint.digs.size() - this->digs.size() : 0);
list<int> digs2 = pad(bigint.digs, bigint.digs.size() < this->digs.size() ? this->digs.size() - bigint.digs.size() : 0);
if (this->sign == bigint.sign) {
sign = this->sign;
digs = add(digs1, digs2);
}
else {
list<int>* greater_digs, * less_digs;
int cmp_result = compare(digs1, digs2);
if (cmp_result < 0) {
less_digs = &digs1;
greater_digs = &digs2;
sign = bigint.sign;
}
else {
greater_digs = &digs1;
less_digs = &digs2;
sign = cmp_result > 0 ? sign = this->sign : 1;
}
digs = trim(subtract(*greater_digs, *less_digs));
}
return Bigint(sign, digs);
}
Bigint Bigint::subtract(const Bigint& bigint) const {
return add(Bigint(-bigint.sign, bigint.digs));
}
Bigint::Bigint(const int& sign, const list<int>& digs) : sign(sign), digs(digs) {}
list<int> Bigint::pad(const list<int>& digs, const int& len) {
list<int> result;
for (int i = 0; i < len; i++) result.push_back(int(0));
result.insert(result.end(), digs.begin(), digs.end());
return result;
}
list<int> Bigint::trim(const list<int>& digs) {
list<int> result;
list<int>::const_iterator iter = digs.begin();
while (iter != digs.end() && *iter == 0) iter++;
if (iter == digs.end()) iter--;
result.insert(result.end(), iter, digs.end());
return result;
}
int Bigint::compare(const list<int>& digs1, const list<int>& digs2) {
int result = 0;
list<int>::const_iterator iter1 = digs1.begin();
list<int>::const_iterator iter2 = digs2.begin();
while (iter1 != digs1.end()) {
if (*iter1 == *iter2) {
iter1++;
iter2++;
continue;
}
if (*iter1 < *iter2) result = -1;
else if (*iter1 > *iter2) result = 1;
break;
}
return result;
}
list<int> Bigint::add(const list<int>& digs1, const list<int>& digs2) {
list<int> result;
list<int>::const_reverse_iterator iter1 = digs1.rbegin();
list<int>::const_reverse_iterator iter2 = digs2.rbegin();
bool carry_flag = false;
while (iter1 != digs1.rend()) {
int val = *iter1 + *iter2 + (carry_flag ? 1 : 0);
carry_flag = val > 9;
if (carry_flag) val -= 10;
result.push_front(val);
iter1++;
iter2++;
}
if (carry_flag) result.push_front(1);
return result;
}
list<int> Bigint::subtract(const list<int>& digs1, const list<int>& digs2) {
list<int> result;
list<int>::const_reverse_iterator iter1 = digs1.rbegin();
list<int>::const_reverse_iterator iter2 = digs2.rbegin();
bool carry_flag = false;
while (iter1 != digs1.rend()) {
int val = *iter1 - *iter2 - (carry_flag ? 1 : 0);
carry_flag = val < 0;
if (carry_flag) val += 10;
result.push_front(val);
iter1++;
iter2++;
}
return result;
}
int main(void) {
cout << Bigint::fromString("2134490128490823084023483024892").add(Bigint::fromString("60981690786891763458749732985")).toString() << endl;
cout << Bigint::fromString("2134490128490823084023483024892").add(Bigint::fromString("-60981690786891763458749732985")).toString() << endl;
cout << Bigint::fromString("-2134490128490823084023483024892").add(Bigint::fromString("60981690786891763458749732985")).toString() << endl;
cout << Bigint::fromString("-2134490128490823084023483024892").add(Bigint::fromString("-60981690786891763458749732985")).toString() << endl;
cout << Bigint::fromString("990").add(Bigint::fromString("900")).toString() << endl;
cout << Bigint::fromString("990").add(Bigint::fromString("-900")).toString() << endl;
cout << Bigint::fromString("-990").add(Bigint::fromString("900")).toString() << endl;
cout << Bigint::fromString("-990").add(Bigint::fromString("-900")).toString() << endl;
cout << Bigint::fromString("-123").subtract(Bigint::fromString("-3456")).toString() << endl;
return 0;
}