高精度小数加法
高精度小数加法
标签(空格分隔): 算法竞赛 高精度
原题在HDU 1753.当时不知道这类题叫高精度运算,只觉得是大数的运算,于是将大数的四则运算起了个名字叫“大数全家桶”,现在想想也很好玩。
网上看到这题用Java写,分分钟变签到题,大家可以看一看,我这里没写。
Problem Description
话说,经过了漫长的一个多月,小明已经成长了许多,所以他改了一个名字叫“大明”。
这时他已经不是那个只会做100以内加法的那个“小明”了,现在他甚至会任意长度的正小数的加法。
现在,给你两个正的小数A和B,你的任务是代表大明计算出A+B的值。
Input
本题目包含多组测试数据,请处理到文件结束。
每一组测试数据在一行里面包含两个长度不大于400的正小数A和B。
Output
请在一行里面输出输出A+B的值,请输出最简形式。详细要求请见Sample Output。
Sample Input
1.1 2.9
1.1111111111 2.3444323343
1 1.1
Sample Output
4
3.4555434454
2.1
显然是一个高位小数加法,不能用double来做,那只能用模拟数组的加法了。下面是我写的答案。注意,当我尝试把将一个小数得小数部分和整数部分分离的代码写成函数时,程序提交总是过不了,不得已,我将它们写在这同一个函数中。正解如下。
#include <stdio.h>
#include <string.h>
#define N 401
int a[N]={0},b[N]={0},c[N]={0},d[N]={0};
int main()
{
char str1[N],str2[N];
while (scanf("%s %s",str1,str2)!=EOF)
{
int i,j,k;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
int len1=strlen(str1),len2=strlen(str2);
for (i=0;str1[i]!='.'&&i<len1;i++);
k=0;
for (j=i+1;j<len1;j++) //小数从高位到低位
a[k++]=str1[j]-'0';
k=0;
for (j=i-1;j>=0;j--) //整数从低位到高位
b[k++]=str1[j]-'0';
k=0;
for (i=0;str2[i]!='.'&&i<len2;i++);
for (j=i+1;j<len2;j++) //小数从高位到低位
c[k++]=str2[j]-'0';
k=0;
for (j=i-1;j>=0;j--) //整数从低位到高位
d[k++]=str2[j]-'0';
k=0;
for (i=N;i>=0;i--) //小数部分相加
{
a[i]+=c[i];
if (i!=0&&a[i]>9)
{
a[i]%=10;
a[i-1]++;
}
else if (i==0&&a[i]>9)
{
a[i]%=10;
b[0]++;
}
}
for (i=0;i<N;i++) //处理整数部分相加
{
b[i]+=d[i];
if (b[i]>9)
{
b[i]%=10;
b[i+1]++;
}
}
for (i=N;i>=0&&b[i]==0;i--); //输出整数部分
for (j=i;j>=0;j--)
printf("%d",b[j]);
for (i=N;i>=0&&a[i]==0;i--); //输出小数部分
if (i>=0)
{
printf(".");
for (j=0;j<=i;j++)
{
printf("%d",a[j]);
}
}
printf("\n");
}
return 0;
}
我在网上找的C语言实现的代码都很长,过百行,窃以为鄙人写的这个最短。
还有我写的那个设函数的代码,我不知道为何不对,也贴出来,望大佬指点迷津。
#include <stdio.h>
#include <string.h>
#define N 401
int f=0;
int a[N],b[N],c[N],d[N];
void store(char str[N],int decimal[N],int integer[N])
{
int i,j,k=0;
int len = strlen(str);
for (i=0;i<len;i++)
{
if (str[i]=='.')
{
f=1;
break;
}
}
for (j=i+1;j<len;j++)
decimal[k++]=str[j]-'0';
k=0;
for (j=i-1;j>=0;j--)
integer[k++]=str[j]-'0';
}
int main()
{
char str1[N],str2[N];
while (scanf("%s%s",str1,str2)!=EOF)
{
memset(a,0,N);
memset(b,0,N);
memset(c,0,N);
memset(d,0,N);
store(str1,a,b);
store(str2,c,d);
int i,j=0;
for (i=N;i>=0;i--)
{
a[i]+=c[i];
if (i!=0&&a[i]>=10)
{
a[i]-=10;
a[i-1]++;
}
if (i==0&&a[i]>=10)
{
a[i]-=10;
b[0]++;
}
}
for (i=0;i<N;i++)
{
b[i]+=d[i];
if (b[i]<=0)
{
break;
}
else if (b[i]>=10)
{
b[i]-=10;
b[i+1]++;
}
}
for (i=N;i>=0;i--)
{
if (b[i]!=0)
j=1;
if (j)
printf("%d",b[i]);
}
if (!j)
printf("0");
for (i=N;i>=0;i--)
if (a[i])
break;
if (i>-1)
printf(".");
if (i>=0)
for (j=0;j<=i;j++)
printf("%d",a[j]);
printf("\n");
}
return 0;
}
上面这段代码运行没问题,但是一提交就WA,我也不知道为什么,希望大家能指点一二。