欢迎测试!
/* 大整数 C 模版 (大整数相加,相乘) 字符串形式输入,s[0]为最高位 author : http://www.cnblogs.com/JMDWQ/ */ # include <stdio.h> # include <string.h> # define MAXN (10000 + 5) /* MAXN -- 输入中整数的最大位数 */ char a[MAXN], b[MAXN], c[2 * MAXN]; int bign_prep(char *s); void str_rev(char *s); int bign_cmp(char *a, char *b); void Add(char *a, char *b, char *c); int Sub(char *a, char *b, char *c); void Mul(char *a, char *b, char *c); void cal(char *a, char *b, char *c, char op); int main() { char opd[5]; while (~scanf("%s%s%s", a, opd, b)) cal(a, b, c, opd[0]); return 0; } /* 处理大整数前的负号,并返回大整数的符号 */ int bign_prep(char *s) { int i; if (s[0] != '-') { for (i = 0; s[i]; ++i) if (s[i] != '0') return 1; return 0; } for (i = 0; s[i]; ++i) s[i] = s[i+1]; return -1; } /* 字符串反转,s 末尾必须是 '\0' */ void str_rev(char *s) { char ch; int i, n, len = strlen(s); n = len >> 1; for (i = 0; i < n; ++i) ch = s[i], s[i] = s[len-1-i], s[len-1-i] = ch; } /* 两个无符号大整数相比较, 返回 a-b 的符号,a==b 时返回 0 */ int bign_cmp(char *a, char *b) { int i, lenx = strlen(a), leny = strlen(b); if (lenx > leny) return 1; if (lenx < leny) return -1; for (i = 0; i < lenx; ++i) if (a[i] > b[i]) return 1; else if (a[i] < b[i]) return -1; return 0; } /* 无符号大整数相加, c = a+b */ void Add(char *a, char *b, char *c) { int i, tmp, ea = 1, eb = 1, carry = 0; str_rev(a), str_rev(b); for (i = 0; a[i]||b[i]; ++i) { if (!a[i]) ea = 0; if (!b[i]) eb = 0; tmp = carry; if (ea) tmp += a[i]-'0'; if (eb) tmp += b[i]-'0'; c[i] = tmp % 10 + '0'; carry = tmp / 10; } if (carry) c[i++] = carry+'0'; while (--i && c[i] == '0') ; c[i+1] = '\0'; str_rev(a), str_rev(b), str_rev(c); } /* c = abs(a-b), 返回 a-b 的符号, a==b时返回0,此时 c == "0" */ int Sub(char *a, char *b, char *c) { char *p, *q; int i, n, tmp, sgnc, eq = 1, carry = 0; sgnc = bign_cmp(a, b); if (sgnc == 0) {c[0] = '0', c[1] = '\0'; return 0;} else if (sgnc > 0) p = a,q = b; else p = b, q = a; str_rev(a), str_rev(b); for (i = 0; p[i]||q[i]; ++i) { tmp = p[i]-'0'-carry; if (!q[i]) eq = 0; if (eq) tmp -= (q[i]-'0'); if (tmp < 0) carry = 1; else carry = 0; c[i] = (tmp+10)%10+'0'; } while (--i && c[i] == '0') ; c[i+1] = '\0'; str_rev(a), str_rev(b), str_rev(c); return sgnc; } /* 无符号大整数相乘 */ void Mul(char *a, char *b, char *c) { int i, j, tmp, lenx = strlen(a), leny = strlen(b); str_rev(a), str_rev(b); memset(c, 0, sizeof(char)*(lenx+leny)); for (i = 0; a[i]; ++i) for (j = 0; b[j]; ++j) { tmp = c[i+j]+(a[i]-'0')*(b[j]-'0'); c[i+j+1] += tmp/10; c[i+j] = tmp%10; } for (i = lenx+leny-1; !c[i]; --i) ; c[i+1] = '\0'; for (; i >= 0; --i) c[i] += '0'; str_rev(a), str_rev(b), str_rev(c); } /* 模拟大数计算器(加法和乘法),直接输出计算结果 */ void cal(char *a, char *b, char *c, char op) { int op_sgn, sgna, sgnb, sub_sgn; sgna = bign_prep(a); sgnb = bign_prep(b); if (op == '+' || op == '-') { op_sgn = (op=='-' ? -1:1); if (op_sgn*sgna*sgnb > 0) { Add(a, b, c); if (sgna < 0) putchar('-'); puts(c); } else { sub_sgn = Sub(a, b, c); if (sub_sgn*sgna < 0) putchar('-'); puts(c); } } else if (op == '*') { Mul(a, b, c); if (sgna*sgnb < 0) putchar('-'); puts(c); } }
使用long long测的,测试程序
下面的没包含负号,整数前包含负号的情况测过了,这个是之前的数据。
/*************************sample**************************/
input
=====
1 - 2
45 - 2
100 - 100
1000 - 1000
1000 - 10000
999 - 999999
1 + 2
45 + 2
100 + 100
1000 + 1000
1000 + 10000
999 + 999999
1 * 2
45 * 2
100 * 100
1000 * 1000
1000 * 10000
999 * 999999
=====
output
=====
-1
43
0
0
-9000
-999000
3
47
200
2000
11000
1000998
2
90
10000
1000000
10000000
998999001
=====
Used: 10 ms, 1448 KB
/*********************************************************/