高效大数模板
1 #include<iostream> 2 #include<string> 3 4 using namespace std; 5 6 const unsigned int MAX = 10000; //整型数组的最大长度 7 const long long WIDTHMAX = 1000000000; //整型数组val[MAX]的元素上限 8 const unsigned int WIDTH = 9; //输出整型数组val[MAX]的元素时的格式宽度,即整型数组val[MAX]的元素的最多位数 9 10 typedef struct node 11 { 12 long long val[MAX]; //用来存储高精度整数 13 unsigned int size; //整型数组的实际长度 14 } BigInt; 15 16 BigInt StrToBigInt(string s); 17 void PrintBigInt(const BigInt & a); 18 int ComPareBigInt(const BigInt & a, const BigInt & b); 19 BigInt MulBigInt(const BigInt & a, const BigInt & b); 20 BigInt AddBigInt(const BigInt & a, const BigInt & b); 21 BigInt SubBigInt(BigInt a, BigInt b); 22 BigInt DivBigInt(const BigInt & a, const BigInt & b); 23 BigInt FacBigInt(unsigned int n); 24 void PowBigInt(BigInt & c, const BigInt & a, unsigned int n); 25 void PowBigInt_2(BigInt & c, const BigInt & a, unsigned int n); 26 BigInt HalfBigInt(BigInt a); 27 28 int main() 29 { 30 string s; 31 BigInt a, b, c; 32 33 cin >> s; 34 a = StrToBigInt(s); 35 cin >> s; 36 b = StrToBigInt(s); 37 38 cout << " "; 39 PrintBigInt(a); 40 cout << "+ "; 41 PrintBigInt(b); 42 c = AddBigInt(a, b); 43 cout << "= "; 44 PrintBigInt(c); 45 cout << endl; 46 47 cout << " "; 48 PrintBigInt(a); 49 cout << "- "; 50 PrintBigInt(b); 51 c = SubBigInt(a, b); 52 cout << "= "; 53 PrintBigInt(c); 54 cout << endl; 55 56 cout << " "; 57 PrintBigInt(a); 58 cout << "* "; 59 PrintBigInt(b); 60 c = MulBigInt(a, b); 61 cout << "= "; 62 PrintBigInt(c); 63 cout << endl; 64 65 cout << " "; 66 PrintBigInt(a); 67 cout << "/ 2 " << endl; 68 c = HalfBigInt(a); 69 cout << "= "; 70 PrintBigInt(c); 71 cout << endl; 72 73 cout << " "; 74 PrintBigInt(a); 75 cout << "/ "; 76 PrintBigInt(b); 77 c = DivBigInt(a, b); 78 cout << "= "; 79 PrintBigInt(c); 80 cout << endl; 81 82 unsigned int n; 83 cin >> n; 84 //cout << n << "! = "; 85 // c = FacBigInt(n); 86 // PrintBigInt(c); 87 // cout << c.size << endl; 88 cout << endl; 89 90 cout << " "; 91 PrintBigInt(a); 92 cout << "^" << n << " = "; 93 PowBigInt(c, a, n); 94 PrintBigInt(c); 95 cout << endl; 96 97 cout << " "; 98 PrintBigInt(a); 99 cout << "^" << n << " = "; 100 PowBigInt_2(c, a, n); 101 PrintBigInt(c); 102 cout << endl; 103 104 system("pause"); 105 return 0; 106 } 107 /* 108 函数名称:PrintBigInt 109 函数功能:输出用整型数组表示的高精度整数 110 输入参数:const BigInt & a:用整型数组表示的高精度整数 111 输出参数:无 112 */ 113 void PrintBigInt(const BigInt & a) 114 { 115 cout << a.val[a.size-1]; 116 for (int i=a.size-2; i>=0; i--) 117 { 118 unsigned w = WIDTHMAX / 10; 119 while (w > 0) 120 { 121 if (a.val[i] >= w) 122 break; 123 cout << 0; 124 w /= 10; 125 } 126 cout << a.val[i]; 127 } 128 cout << endl; 129 } 130 /* 131 函数名称:StrToBigInt 132 函数功能:把元素为数字的字符串转换为用整型数组表示的高精度整数 133 输入参数:string s:存储数字的字符串 134 输出参数:BigInt:返回用整型数组表示的高精度整数 135 */ 136 BigInt StrToBigInt(string s) 137 { 138 BigInt a; 139 a.size = 0; 140 int i = s.size(); 141 unsigned long long sum = 0; 142 while ( i>=WIDTH) 143 { 144 for (int j=i-WIDTH; j<i; j++) 145 sum = sum * 10 + (s[j] - '0'); 146 a.val[a.size++] = sum; 147 sum = 0; 148 i -= WIDTH; 149 } 150 if (i > 0) 151 { 152 for (int j=0; j<i; j++) 153 sum = sum * 10 + (s[j] - '0'); 154 a.val[a.size++] = sum; 155 } 156 return a; 157 } 158 /* 159 函数名称:AddBigInt 160 函数功能:高精度整数加法 161 输入参数:const BigInt & a:用整型数组表示的高精度整数加数 162 const BigInt & b:用整型数组表示的高精度整数加数 163 输出参数:BigInt:返回用整型数组表示的高精度整数和 164 */ 165 BigInt AddBigInt(const BigInt & a, const BigInt & b) 166 { 167 //逆序计算a+b,则从低位开始计算 168 BigInt c; 169 unsigned long long carry = 0; 170 unsigned int i = 0; 171 c.size = 0; 172 while (i < a.size && i < b.size) 173 { 174 c.val[c.size++] = (a.val[i] + b.val[i] + carry) % WIDTHMAX; 175 carry = (a.val[i] + b.val[i] + carry) / WIDTHMAX; 176 i++; 177 } 178 while (i < a.size) 179 { 180 c.val[c.size++] = (a.val[i] + carry) % WIDTHMAX; 181 carry = (a.val[i] + carry) / WIDTHMAX; 182 i++; 183 } 184 while (i < b.size) 185 { 186 c.val[c.size++] = (b.val[i] + carry) % WIDTHMAX; 187 carry = (b.val[i] + carry) / WIDTHMAX; 188 i++; 189 } 190 if (carry > 0) 191 c.val[c.size++] = carry; 192 return c; 193 } 194 /* 195 函数名称:SubBigInt 196 函数功能:高精度整数减法 197 输入参数:BigInt a:用整型数组表示的高精度整数被减数 198 BigInt b:用整型数组表示的高精度整数减数 199 输出参数:BigInt:返回用整型数组表示的高精度整数差 200 */ 201 BigInt SubBigInt(BigInt a, BigInt b) 202 { 203 BigInt c; 204 c.size = 0; 205 if (ComPareBigInt(a, b) == 0) 206 { 207 c.size = 1; 208 c.val[0] = 0; 209 return c; 210 } 211 bool flag = false; 212 if (ComPareBigInt(a, b) < 0)//交换,并得到一个负号 213 { 214 flag = true; 215 BigInt temp = a; 216 a = b; 217 b = temp; 218 } 219 unsigned int i = 0; 220 while (i < b.size) 221 { 222 if (a.val[i] >= b.val[i]) 223 c.val[c.size++] = a.val[i] - b.val[i]; 224 else 225 { 226 a.val[i+1] -= 1; 227 c.val[c.size++] = a.val[i] + WIDTHMAX - b.val[i]; 228 } 229 i++; 230 } 231 while (i < a.size) 232 { 233 if (a.val[i] < 0) 234 { 235 a.val[i+1] -= 1; 236 a.val[i] += WIDTHMAX; 237 } 238 c.val[c.size++] = a.val[i]; 239 i++; 240 } 241 //消除多余的高位0 242 while (c.val[c.size-1] == 0) 243 c.size--; 244 245 if (flag)//如果是负数,加上负号 246 c.val[c.size-1] = -c.val[c.size-1]; 247 return c; 248 } 249 /* 250 函数名称:ComPareBigInt 251 函数功能:比较两个高精度整数的大小 252 输入参数:BigInt a:用整型数组表示的高精度整数被减数 253 BigInt b:用整型数组表示的高精度整数减数 254 输出参数:int:a > b返回1,a = b返回0,a < b返回-1 255 */ 256 int ComPareBigInt(const BigInt & a, const BigInt & b) 257 { 258 if (a.size > b.size) 259 return 1; 260 if (a.size < b.size) 261 return -1; 262 263 for (int i=a.size-1; i>=0; i--) 264 { 265 if (a.val[i] > b.val[i]) 266 return 1; 267 if (a.val[i] < b.val[i]) 268 return -1; 269 } 270 return 0; 271 } 272 /* 273 函数名称:MulBigInt 274 函数功能:高精度整数乘法 275 输入参数:const BigInt & a:用整型数组表示的高精度整数被乘数 276 const BigInt & b:用整型数组表示的高精度整数乘数 277 输出参数:BigInt:返回用整型数组表示的高精度整数乘积 278 */ 279 BigInt MulBigInt(const BigInt & a, const BigInt & b) 280 { 281 if (a.size == 1 && a.val[0] == 0) 282 return a; 283 if (b.size == 1 && b.val[0] == 0) 284 return b; 285 286 BigInt c; 287 for (int i=0; i<MAX; i++) //全部赋初值为0 288 c.val[i] = 0; 289 for (int i=0, j=0; i<b.size; i++) 290 { 291 for (j=0; j<a.size; j++) 292 { 293 c.val[i+j] += a.val[j] * b.val[i]; 294 c.val[i+j+1] += c.val[i+j] / WIDTHMAX; 295 c.val[i+j] %= WIDTHMAX; 296 } 297 c.size = i + j; 298 if (c.val[c.size] != 0)//最高位有进位 299 c.size++; 300 } 301 return c; 302 } 303 /* 304 老版本: 305 BigInt MulBigInt2(const BigInt & a, const BigInt & b) 306 { 307 if (a.size == 1 && a.val[0] == 0) 308 return a; 309 if (b.size == 1 && b.val[0] == 0) 310 return b; 311 312 BigInt c, tc; 313 unsigned long long carry = 0; 314 c.size = 0; 315 for (int i=0, j=0; i<b.size; i++) 316 { 317 for (j=0; j<i; j++)//先在临时和tc的低位补足0 318 tc.val[j] = 0; 319 carry = 0; 320 for (j=0; j<a.size; j++) 321 { 322 tc.val[i+j] = (a.val[j] * b.val[i] + carry) % WIDTHMAX; 323 carry = (a.val[j] * b.val[i] + carry) / WIDTHMAX; 324 } 325 tc.size = i + j; 326 if (carry > 0) 327 tc.val[tc.size++] = carry; 328 //累加到c中 329 c = AddBigInt(tc, c); 330 } 331 return c; 332 } 333 */ 334 335 /* 336 函数名称:FacBigInt 337 函数功能:高精度整数阶乘 338 输入参数:unsigned int n:正整数 339 输出参数:BigInt:返回用整型数组表示的高精度整数阶乘 340 */ 341 BigInt FacBigInt(unsigned int n) 342 { 343 BigInt s, c; 344 c.size = s.size = 1; 345 s.val[0] = 1; 346 for (unsigned long long i=2; i<=n; i++) 347 { 348 c.val[0] = i; 349 s = MulBigInt(s, c); 350 } 351 return s; 352 } 353 354 /* 355 函数名称:PowBigInt 356 函数功能:递归高效算法求高精度整数幂 357 输入参数:BigInt & c:存储高精度整数幂的整型数组 358 const BigInt & a:用整型数组表示的高精度整数底数 359 long long n: 指数 360 */ 361 void PowBigInt(BigInt & c, const BigInt & a, unsigned int n) 362 { 363 if (n == 1) 364 { 365 c = a; 366 return ; 367 } 368 if (n == 0 || (a.size == 1 && a.val[0] == 1)) 369 { 370 c.size = c.val[0] = 1; 371 return ; 372 } 373 374 PowBigInt(c, a, n/2); //递归求高精度整数幂 375 376 c = MulBigInt(c, c); //a^n = a^(n/2)*a^(n/2)*f(a) 377 if (n % 2 == 1) //其中f(a) = 1(n%2==0)或f(a) = a(n%2==1) 378 c = MulBigInt(a, c); 379 } 380 381 /* 382 函数名称:PowBigInt_2 383 函数功能:非递归高效算法求高精度整数幂 384 输入参数:BigInt & c:存储高精度整数幂的整型数组 385 const BigInt & a:用整型数组表示的高精度整数底数 386 long long n: 指数 387 */ 388 void PowBigInt_2(BigInt & c, const BigInt & a, unsigned int n) 389 { 390 int stack[MAX] = {0}; 391 int top = 0; 392 while (n > 0) //利用一个栈来存储n的状态:奇数还是偶数 393 { 394 stack[top++] = n % 2; 395 n /= 2; 396 } 397 c.size = c.val[0] = 1; 398 for (int i=top-1; i>=0; i--) 399 { 400 c = MulBigInt(c, c); //a^n = a^(n/2)*a^(n/2)*f(a) 401 if (stack[i] == 1) //其中f(a) = 1(n%2==0)或f(a) = a(n%2==1) 402 c = MulBigInt(a, c); 403 } 404 } 405 406 /* 407 函数名称:DivBigInt 408 函数功能:二分法实现高精度整数除法 409 输入参数:const BigInt & a:用整型数组表示的高精度整数被除数 410 const BigInt & b:用整型数组表示的高精度整数除数 411 输出参数:BigInt:返回用整型数组表示的高精度整数商 412 */ 413 BigInt DivBigInt(const BigInt & a, const BigInt & b) 414 { 415 BigInt high, low, mid, one, c; 416 if ((a.size == 1 && a.val[0] == 0) || (b.size == 1 && b.val[0] == 0)) 417 { 418 c.size = 1; 419 c.val[0] = 0; 420 return c; 421 } 422 423 one.size = 1; //值为1的高精度整数 424 one.val[0] = 1; 425 high = a; //上界 426 low.size = 1; //下界 427 low.val[0] = 0; 428 while (ComPareBigInt(low, high) < 0) 429 { 430 mid = HalfBigInt(AddBigInt(high, low)); //中间数 431 c = MulBigInt(mid, b); 432 if (ComPareBigInt(c, a) == 0) 433 return mid; 434 else if (ComPareBigInt(c, a) < 0) 435 low = AddBigInt(mid, one); 436 else 437 high = SubBigInt(mid, one); 438 } 439 c = MulBigInt(low, b); 440 if (ComPareBigInt(c, a) <= 0) 441 return low; 442 else 443 return SubBigInt(low, one); 444 } 445 446 /* 447 函数名称:HalfBigInt 448 函数功能:高精度整数求半 449 输入参数:BigInt a:用整型数组表示的高精度整数 450 输出参数:BigInt:返回用整型数组表示的高精度整数的一半 451 */ 452 BigInt HalfBigInt(BigInt a) 453 { 454 BigInt c; 455 c.size = a.size; 456 for (int i=a.size-1; i>0; i--) 457 { 458 c.val[i] = a.val[i] / 2; 459 if (a.val[i] % 2 == 1) 460 a.val[i-1] += WIDTHMAX; 461 } 462 c.val[0] = a.val[0] / 2; 463 if (c.size > 0 && c.val[c.size-1] == 0) 464 c.size--; 465 466 return c; 467 }