您的位置:首页 > 其它

[UVa] 465 - Overflow

2016-10-27 19:11 417 查看
破水题,耗我精力,颓我精神。。。

按照《算法入门经典》的题目列表来做,前几题用到了高精度,所以这一题打算直接用高精度计算,几分钟水过去。没想到一水就是几个小时。最后终于在百度了好多博客之后,找到了自己的bug。

0000000000000001 + 0000000000000001 这样的数据我是过不去的,字符串转换为高精度数的时候我忘记清除前导0了。

题目:

Write a program that reads an expression consisting of two non-negative integer and an operator.

Determine if either integer or the result of the expression is too large to be represented as a “normal”

signed integer (type integer if you are working Pascal, type int if you are working 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 containing as 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


题目大意就是输入两个数和一个操作符,判断这两个数和计算结果是否超过int的最大值。

我的代码没什么技巧,也不值得别人参考,就是为了再熟悉一下高精度计算才这么写。

果然找到了一个致命的bug。我的高精度还得再完善。

代码:

#include<stdio.h>
#include<string.h>
#define MAXN 10001

const int base = 10000;
const int digit = 4;
typedef int bignum[MAXN];

char str1[MAXN], str2[MAXN], c;
bignum num1, num2, ans;

void str2num(char *str, bignum num);
void printBIgnum(bignum num);
void add(bignum num1, bignum num2, bignum ans);
void mul(bignum num1, bignum num2, bignum ans);
int isOverflow_int(bignum num);

int main()
{
memset(str1, 0, sizeof(str1));
memset(str2, 0, sizeof(str2));
while(scanf("%s %c %s", str1, &c, str2) == 3)
{
printf("%s %c %s\n", str1, c, str2);
str2num(str1, num1);
str2num(str2, num2);
if(isOverflow_int(num1)) printf("first number too big\n");
if(isOverflow_int(num2)) printf("second number too big\n");
if(c == '+') add(num1, num2, ans);
else mul(num1, num2, ans);
if(isOverflow_int(ans)) printf("result too big\n");

memset(str1, 0, sizeof(str1));
memset(str2, 0, sizeof(str2));
}
return 0;
}

void str2num(char *str, bignum num)
{
memset(num, 0, sizeof(bignum));
*num = 0;
int len = strlen(str);
while(len > 0)
{
int d = len > digit ? digit : len;
int i, n = 0, w = 1;
for(i = 0; i < d; i++)
{
n += (str[len-1-i] - '0') * w;
w *= 10;
}
num[++*num] = n;
len -= d;
}
while(!num[*num] && *num > 0) --*num;
}

void printBIgnum(bignum num)
{
printf("%d", num[*num]);
int i;
for(i = *num - 1; i > 0; i--) printf("%04d", num[i]);
printf("\n");
}

void add(bignum num1, bignum num2, bignum ans)
{
memset(ans, 0, sizeof(bignum));
*ans = *num1 > *num2 ? *num1 : *num2;
int pos, carry = 0;
for(pos = 1; pos <= *ans; pos++)
{
carry += num1[pos] + num2[pos];
ans[pos] = carry % base;
carry /= base;
}
while(carry)
{
ans[++*ans] = carry % base;
carry /= base;
}
}

void mul(bignum num1, bignum num2, bignum ans)
{
memset(ans, 0, sizeof(bignum));
int i, j, carry = 0;
for(j = 1; j <= *num2; j++)
{
for(i = 1; i <= *num1; i++)
{
ans[i+j-1] += num1[i] * num2[j] + carry;
carry = ans[i+j-1] / base;
ans[i+j-1] %= base;
}
i = *num1 + j;
while(carry)
{
ans[i++] = carry % base;
carry /= base;
}
}
*ans = *num1 + *num2;
while(!ans[*ans] && *ans > 0) --*ans;
}

int isOverflow_int(bignum num)
{
/*2147483647*/
if(*num < 3) return 0;
else if(*num > 3 || num[3] > 21) return 1;
else if(num[3] < 21) return 0;
else if(num[2] > 4748) return 1;
else if(num[2] < 4748) return 0;
else if(num[1] > 3647) return 1;
else return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 高精度 uva bug