test
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 }