UVa 465 Overflow——WA
上次那个大数开方的高精度的题,UVa113 Power of Cryptography,直接两个double变量,然后pow(x, 1 / n)就A过去了。
怎么感觉UVa上高精度的题测试数据不给力啊。。。
话说回来,我写了100+行代码,WA了,后来考虑到要忽略前导0,又WA了,实在不知道哪出问题了。
Write a program that reads an expression consisting of twonon-negative integer and an operator. Determine if either integer or the resultof the expression is too large to be represented as a ``normal'' signed integer(type integer if you areworking Pascal, type int if you areworking in C).
Input
An unspecified number of lines. Each line will contain an integer,one of the two operators + or *, and another integer.
Output
For each line of input, print the input followed by 0-3 lines containingas many of these three messages as are appropriate: ``first number too big'',``second number too big'',``result too big''.
Sample Input
300 + 3
9999999999999999999999 + 11
Sample Output
300 + 3
9999999999999999999999 + 11
first number too big
result too big
看到好多人用atof(),就是把一个字符串转化成double型数据。
下面是百科内容:
如果用double的话,直接将数据和2^31-1进行比较判断是否溢出就好了。
这是别人的AC代码。
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 using namespace std; 7 8 const int INT = 2147483647; 9 const int maxn = 300; 10 char a[maxn], b[maxn], c; 11 12 int main(void) 13 { 14 #ifdef LOCAL 15 freopen("465in.txt", "r", stdin); 16 #endif 17 18 double x, y, z; 19 while(scanf("%s %c %s", a, &c, b) == 3) 20 { 21 printf("%s %c %s\n", a, c, b); 22 x = atof(a); 23 y = atof(b); 24 if(c == '+') 25 z = x + y; 26 if(c == '*') 27 z = x * y; 28 if(x > INT) 29 cout << "first number too big" << endl; 30 if(y > INT) 31 cout << "second number too big" << endl; 32 if(z > INT) 33 cout << "result too big" << endl; 34 } 35 return 0; 36 }
可我还是想把自己WA的代码贴出来,毕竟是花了大心思用心去写的。
而且这个代码也通过了样例测试和我自己能想到的各种极端的情况。
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 300; 8 const char *INT = "2147483647"; 9 char a[maxn], b[maxn], c[maxn], result[maxn]; 10 int x[maxn], y[maxn], z[maxn]; 11 bool judge(char c[], int l); 12 void fun(char c[]); 13 14 int main(void) 15 { 16 #ifdef LOCAL 17 freopen("465in.txt", "r", stdin); 18 #endif 19 20 char op; 21 while(gets(c)) 22 { 23 cout << c << endl; 24 sscanf(c, "%s %c %s", a, &op, b); 25 fun(a); 26 fun(b); 27 int la = strlen(a); 28 int lb = strlen(b); 29 bool flaga, flagb; 30 if(flaga = judge(a, la)) 31 cout << "first number too big" << endl; 32 if(flagb = judge(b, lb)) 33 cout << "second number too big" << endl; 34 35 int i, j; 36 //对结果是否溢出进行处理 37 if(op == '+') 38 { 39 if(flaga || flagb)//加法运算有一个加数溢出那么结果溢出 40 { 41 cout << "result too big" << endl; 42 continue; 43 } 44 memset(x, 0, sizeof(x)); 45 memset(y, 0, sizeof(y)); 46 for(i = la - 1; i >= 0; --i) 47 x[la - 1 - i] = a[i] - '0'; 48 for(i = lb - 1; i >= 0; --i) 49 y[lb - 1 - i] = b[i] - '0'; 50 for(i = 0; i < lb; ++i)//高精度加法运算 51 { 52 x[i] = x[i] + y[i]; 53 if(x[i] > 10) 54 { 55 j = i; 56 while(x[j] > 10)//处理连续进位的问题 57 { 58 x[j++] -= 10; 59 ++x[j]; 60 } 61 } 62 } 63 } 64 65 if(op == '*') 66 { 67 //如果乘数为0的话,那么结果不溢出 68 if((la == 1 && a[0] == '0') || (lb == 1 && b[0] == '0')) 69 continue; 70 else 71 { 72 if((flaga || flagb) || (la + lb > 11))//有一个乘数溢出或者两乘数位数之和超过11位 73 { 74 cout << "result too big" << endl; 75 continue; 76 } 77 memset(x, 0, sizeof(x)); 78 memset(y, 0, sizeof(y)); 79 for(i = la - 1; i >= 0; --i) 80 x[la - 1 - i] = a[i] - '0'; 81 for(i = lb - 1; i >= 0; --i) 82 y[lb - 1 - i] = b[i] - '0'; 83 84 for(i = 0; i < lb; ++i) 85 { 86 int s = 0, c = 0; 87 for(j = 0; j < maxn; ++j) 88 { 89 s = x[j] * y[i] + c; 90 x[i + j] = s % 10; 91 c = s / 10; 92 } 93 } 94 } 95 } 96 97 for(i = maxn - 1; i >= 0; --i) 98 if(x[i] != 0) 99 break; 100 memset(result, 0, sizeof(result)); 101 j = 0; 102 for(; i >= 0; --i) 103 result[j++] = x[i] + '0';//将结果转化为字符串好进行判断 104 if(judge(result, strlen(result))) 105 cout << "result too big" << endl; 106 } 107 return 0; 108 } 109 //判断一个字符串是否会溢出 110 bool judge(char c[], int l) 111 { 112 if(l > 10) 113 return true; 114 if(l < 10) 115 return false; 116 if(strcmp(c, INT) > 0) 117 return true; 118 return false; 119 } 120 //忽略字符串的前导0 121 void fun(char c[]) 122 { 123 if(c[0] != '0') 124 return; 125 int i = 0, j = 0; 126 while(c[i] == '0') 127 ++i; 128 for(; c[i] != '\0'; ++i) 129 c[j++] = c[i]; 130 c[j] = '\0'; 131 }