-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBigNum.cpp
More file actions
106 lines (91 loc) · 2.03 KB
/
BigNum.cpp
File metadata and controls
106 lines (91 loc) · 2.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
class BigNum {
public:
BigNum(int x) : data_(std::to_string(x)) {}
BigNum(string x) : data_(x) {
Trim();
}
std::string String() { return data_.empty() ? "0" : data_; }
BigNum Add(BigNum other) {
std::string& A = data_;
std::string& B = other.data_;
bool carry = false;
std::string res = "";
int idx1 = A.size() - 1;
int idx2 = B.size() - 1;
while (idx1 >= 0 && idx2 >= 0) {
res += GetDigitSum(A[idx1--], B[idx2--], &carry);
}
while (idx1 >= 0) {
res += GetDigitSum(A[idx1--], &carry);
}
while (idx2 >= 0) {
res += GetDigitSum(B[idx2--], &carry);
}
if (carry) {
res += '1';
}
std::reverse(res.begin(), res.end());
return BigNum(res);
}
BigNum Multiply(BigNum other) {
std::string& A = data_;
std::string& B = other.data_;
BigNum res(0);
int level = 0;
for (int i = A.size() - 1; i >= 0; i--) {
std::string tmp;
tmp.resize(level++);
fill(tmp.begin(), tmp.end(), '0');
int carry = 0;
for (int j = B.size() - 1; j >= 0; j--) {
tmp += GetDigitMulti(A[i], B[j], &carry);
}
if (carry) {
tmp += (carry + '0');
}
std::reverse(tmp.begin(), tmp.end());
res = res.Add(tmp);
}
return res;
}
private:
void Trim() {
std::reverse(data_.begin(), data_.end());
int idx = data_.size() - 1;
while (idx >= 0 && data_[idx] == '0') {
idx--;
}
data_.resize(idx + 1);
std::reverse(data_.begin(), data_.end());
}
char GetDigitMulti(char digit1, char digit2, int* carry) {
char res = ((digit1 - '0') * (digit2 - '0')) + *carry;
*carry = 0;
if (res >= 10) {
*carry = res/10;
res = res % 10;
}
return res + '0';
}
char GetDigitSum(char digit, bool* carry) {
char res = (digit - '0') + *carry;
if (res >= 10) {
res -= 10;
*carry = true;
} else {
*carry = false;
}
return res + '0';
}
char GetDigitSum(char digit1, char digit2, bool* carry) {
char res = (digit1 - '0') + (digit2 - '0') + *carry;
if (res >= 10) {
res -= 10;
*carry = true;
} else {
*carry = false;
}
return res + '0';
}
std::string data_;
};