A+B Problem IV

5 篇文章 0 订阅
描述
acmj最近发现在使用计算器计算高精度的大数加法时很不方便,于是他想着能不能写个程序把这个问题给解决了。
输入
包含多组测试数据
每组数据包含两个正数A,B(可能为小数且位数不大于400)
输出
每组输出数据占一行,输出A+B的结果,结果需要是最简的形式。
样例输入
1.9 0.1
0.1 0.9
1.23 2.1
3 4.0
样例输出
2
1
3.33
7

 

做这个题的时候WA了很多次,还是因为问题考虑的不全面。
比如下面几组数据:0.0+1.2   999+1 (考虑整数的直接进位)    0.98+0.10     1+1    9+0.1   0.1+9(考虑一个浮点数加一个整数的情况)

我的方法比较繁琐……
定义四个数组分别存两个运算数,得数的整数部分和小数部分。
其中整数部分数字要倒着存储,0001000 1后面的0要输出, 1前面的0不输出。
小数部分数字要正着存储,因为0.0000100 这种情况下,1前面的0还是要输出 倒着存不会输出1之前的0,1后面的0可以控制不输出

函数add1 用于计算整数部分 add2计算小数部分,如果小数部分向整数部分有进位,调用add3函数。
如果一个数是整数一个数是浮点数,那么直接把两数字的整数部分相加,小数部分直接取浮点数的小数部分。
输出的时候要从第一个不是0的数开始输出。

 

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define SIZE 1000
int c[SIZE * 2];//存储整数部分
int d[SIZE * 2];//存储小数部分

void add1(char a[], char b[], int m, int n)
{//整数部分相加
	int a1[SIZE], b1[SIZE];
	memset(a1, 0, sizeof(a1));
	memset(b1, 0, sizeof(b1));
	int i, j, k, max;
	max = m > n ? m : n;
	for(i = 0, j = m - 1; i < m; i++, j--)
	{
		a1[i] = a[j] - '0';
	}
	for(i = 0, j = n - 1; i < n; i++, j--)
	{
		b1[i] = b[j] - '0';
	}

	for(i = 0, k = 0; i < max; i++)
	{
		c[i] = (a1[i] + b1[i] + k) % 10;
	}
	if(k != 0)
		c[i] = k;
}

int add2 (char a[], char b[], int m, int n)
{//小数部分相加
	int i, j, k, f, l;
	int t1 = strlen(a);
	int t2 = strlen(b);
	//小数部分位数要相同,位数少的在后面补0
	for(i = m + 1; a[i] != '\0'; i++)
	{}
	for(j = n + 1; b[j] != '\0'; j++)
	{}
	f = i > j ? i : j;
	int max = (t1 - m - 1) > (t2 - n - 1) ? (t1 - m - 1) : (t2 - n - 1);
	if((t1 - m - 1) > (t2 - n - 1))
	{
		int t = (t1 - m - 1) - (t2 - n - 1);
		while (t--)
		{//补0操作
			b[j++] = '0';
		}
		b[j++] = '\0';
	}
	if((t1 - m - 1) < (t2 - n - 1))
	{
		int t = (t2 - n - 1) - (t1 - m - 1);
		while (t--)
		{//补0操作
			a[i++] = '0';
		}
		a[i++] = '\0';
	}
	for(l = max - 1, i = m + max, j = n + max, k = 0; l >= 0; i--, j--, l--)
	{
		d[l] = ((a[i] - '0') + (b[j] - '0') + k) % 10;
		k = ((a[i] - '0') + (b[j] - '0') + k) / 10;
	}
	return k;
}

void add3 (int k)
{//小数向整数进位相加
	int i, n;
	c[0] += k;
	for(i = 1, n = 0; i < SIZE * 2 - 1; i++)
	{
		c[i] += c[i - 1] / 10;
		c[i - 1] %= 10;
	}
}

int main (void)
{
	int i, j, len1, len2, k1, k2, l, m;
	char a[SIZE], b[SIZE];
	while (1)
	{
		k1 = 0, k2 = 0;
		memset(a, 0, sizeof(a));
		memset(b, 0, sizeof(b));
		memset(c, 0, sizeof(c));
		memset(d, 0, sizeof(d));
		scanf("%s%s", a, b);
		if(!isdigit(a[0]))
			return 0;
		
		len1 = strlen(a);
		for(i = 0; i < len1; i++)
		{
			if(a[i] == '.')
				break;
		}

		len2 = strlen(b);
		for(j = 0; j < len2; j++)
		{
			if(b[j] == '.')
				break;
		}
		/*如果有小数部分*/
		//如果两个数都有小数部分
		if(i != len1 && j != len2)
		{
			k2 = add2(a, b, i, j);
		}
		//两个数中如果只有一个数有小数部分,直接把有小数部分搬到d数组中就可以
		if(i == len1 && j != len2)
		{
			for(m = 0, l = j + 1; b[l] != '\0'; m++, l++)
				d[m] = b[l] - '0';
		}
		if(i != len1 && j == len2)
		{
			for(m = 0, l = i + 1; a[l] != '\0'; m++, l++)
				d[m] = a[l] - '0';
		}
		//算整数部分
		add1(a, b, i, j);	
		//如果小数有进位
		if(k2 != 0)
			add3(k2);
		//输出整数
		i = SIZE * 2 - 1;
		while(c[i] == 0 && i > 0)
		{
			i--;
		}
		for(; i >= 0; i--)
			printf("%d", c[i]);

		//输出小数
		i = SIZE * 2 - 1;
		while (d[i] == 0 && i >= 0)
		{
			i--;
		}
		//printf("\ni = %d\n", i);
		if(i != -1)
		{
			printf(".");
			for(j = 0; j <= i; j++)
				printf("%d",d[j]);
		}
		printf("\n");
	}
	return 0;
}                


 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值