1 /*
2 各种基本数值运算的高精度合集,部分代码参考猥琐帝@xiehaoyun2012,感谢其无私奉献的精神
3 包括:
4 两个高精度正整数加法
5 两个高精度正整数乘法
6 两个高精度正整数减法
7 两个高精度正整数除法
8 两个高精度正整数求余
9 两个高精度正整数数求最大公约数
10 两个高精度正整数数求最小公倍数
11 注意:不排除还有没被发现的Bug!
12 */
13
14 #include <iostream>
15 #include <string>
16
17 using namespace std;
18
19 //清除前缀0,如果结果是空字符串则设为0
20 inline void clear(string& a){
21 while(a.length()>0 && a[0]=='0')
22 a.erase(0, 1);
23 if(a == "")
24 a = "0";
25 }
26
27 //如果a>=b则返回真(如果包含前缀零会被消除)
28 bool isBigger(string a, string b){
29 clear(a);
30 clear(b);
31 if(a.length() > b.length())
32 return true;
33 if(a.length()==b.length() && a>=b)
34 return true;
35 return false;
36 }
37
38
39 //两个高精度正整数加法 a+b
40 string stringAddString(string a, string b){
41 //1、对位,将两个数补零直到其具有相同长度
42 while(a.length() < b.length())
43 a = '0' + a;
44 while(a.length() > b.length())
45 b = '0' + b;
46 //2、补零,在开头再加一个0以便进位
47 a = '0' + a;
48 b = '0' + b;
49 //3、从低位开始相加,注意进位
50 for(int i=a.length()-1; i>=0; i--){
51 a[i] = a[i] + b[i] - '0';
52 if(a[i] > '9'){
53 a[i] = a[i] - 10;
54 a[i-1] += 1;
55 }
56 }
57 clear(a);
58 return a;
59 }
60
61 //两个高精度正整数减法 a-b
62 string stringSubString(string a, string b){
63 bool aBigger = true;
64 //1、对位,将两个数补零直到其具有相同长度
65 while(a.length() < b.length())
66 a = '0' + a;
67 while(a.length() > b.length())
68 b = '0' + b;
69 //2、推测结果正负值,调整为前大后小
70 if(a < b)
71 {
72 aBigger = false;
73 string buf = b;
74 b = a;
75 a = buf;
76 }
77 //3、从低位开始相减,注意借位
78 for(int i=a.length()-1; i>=0; i--){
79 if(a[i] >= b[i]){
80 a[i] = a[i] - (b[i] - '0');
81 }else{
82 a[i] = a[i] + 10;
83 a[i-1] -= 1;
84 a[i] = a[i] - (b[i] - '0');
85 }
86 }
87 clear(a);
88 if(!aBigger)
89 a = '-' + a;
90 return a;
91 }
92
93 //两个高精度正整数乘法 a*b
94 //依赖加法
95 string stringMultString(string a, string b){
96 string result = "0";
97 if(a.length() < b.length()){
98 string buf = a;
99 a = b;
100 b = buf;
101 }
102 //多位数乘一位数可以直接使用加法
103 //多位数乘以形如d*10^n的数可以转化为多位数乘以一位数
104 //多位数乘以多位数可以转化为若干个多位数乘以一位数相加
105 for(int i=b.length()-1; i>=0; i--){
106 for(int j=0; j<b[i]-'0'; j++){
107 result = stringAddString(result, a);
108 }
109 a = a + '0';
110 }
111 clear(result);
112 return result;
113 }
114
115 //两个高精度正整数除法 a/b
116 //依赖减法
117 string stringDivString(string a, string b){
118 clear(a);
119 clear(b);
120 if(b == "0")
121 return "Error!";
122
123 string result = "";
124 string remainder = "";
125 //从高位开始除,和手算除法一样
126 // 一旦取位刚好大于被除数则开始用减法求商
127 for(int i=0; i<a.length(); i++){
128 remainder = remainder + a[i];
129 result = result + '0';
130 while(isBigger(remainder, b)){
131 result[result.length()-1]++;
132 remainder = stringSubString(remainder, b);
133 }
134 }
135 clear(result);
136 return result;
137 }
138
139 //两个高精度正整数求余 a%b
140 //依赖减法
141 string stringModString(string a, string b){
142 clear(a);
143 clear(b);
144 if(b == "0")
145 return "Error!";
146
147 string result = "";
148 string remainder = "";
149 //和除法唯一的区别就是返回值不一样
150 for(int i=0; i<a.length(); i++){
151 remainder = remainder + a[i];
152 result = result + '0';
153 while(isBigger(remainder, b)){
154 result[result.length()-1]++;
155 remainder = stringSubString(remainder, b);
156 }
157 }
158 clear(remainder);
159 return remainder;
160 }
161
162 //两个高精度数求最大公约数 gcd(a,b)
163 //依赖求余
164 string stringGcd(string a, string b){
165 clear(a);
166 clear(b);
167 if(!isBigger(a, b)){
168 string buf = a;
169 a = b;
170 b = buf;
171 }
172 //使用辗转相除法求最大公约数
173 if(b == "0"){
174 return a;
175 }else{
176 return stringGcd(b, stringModString(a, b));
177 }
178 }
179
180 //两个高精度数求最小公倍数 lcm(a,b)
181 //依赖乘法
182 //依赖除法
183 //依赖最大公约数
184 string stringLcm(string a, string b){
185 clear(a);
186 clear(b);
187 string buf = stringMultString(a, b);
188 //使用公式 lcm(a,b)=a*b/gcd(a,b)
189 if(buf == "0"){
190 return "0";
191 }else{
192 return stringDivString(buf, stringGcd(a, b));
193 }
194 }
195
196 int main()
197 {
198 string choose;
199 string a, b;
200 while (1){
201 cout << "请输入两个正整数:";
202 cin >> a >> b;
203 cout << "a + b = " << stringAddString(a, b) << endl
204 << "a - b = " << stringSubString(a, b) << endl
205 << "a * b = " << stringMultString(a, b) << endl
206 << "a / b = " << stringDivString(a, b) << endl
207 << "a % b = " << stringModString(a, b) << endl
208 << "gcd(a, b) = " << stringGcd(a, b) << endl
209 << "lcm(a, b) = " << stringLcm(a, b) << endl;
210 cout << "输入\"q\"退出,人以其他字符继续:";
211 cin >> choose;
212 if(choose == "q")
213 break;
214 }
215 return 0;
216 }