大数

paidream 2013-10-21 02:05:44
A+B Problem IV
时间限制:1000 ms | 内存限制:65535 KB
难度:3
描述
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
来源

一道高精度加法的题目。
由于数据中可能既有小数又有整数,所以我把整数变成小数(后面加".0"),从而化为两个小数相加的问题。
找小数点的时候,先判断它是否有末尾0,把末尾0先消去(最少保留一个)。
然后把小数点对齐,按照A+B(二)的做法先把数组倒置,然后对应位相加。

#include <stdio.h>  
#include <string.h>
#define max(a,b) a>b?a:b
struct Num
{
int len,back;
char num[800];
}A,B;
void swap(char &a,char &b)
{
a ^= b;
b ^= a;
a ^= b;
}
void Init(Num &c)
{
c.len = strlen(c.num);
char *p = strchr(c.num,'.');
if(p == NULL)
{
c.num[c.len++]='.';
c.num[c.len++]='0';
c.back = 1;
}
else
{
int point_loc = p - c.num;
for(int i=c.len-1;i>=point_loc+2;i--)
{
if(c.num[i] != '0')
break;
c.len--;
}
c.back = c.len - 1 - point_loc;
}
}
void Reverse(Num &c)
{
for(int i=0;i<c.len-1-i;i++)
swap(c.num[i],c.num[c.len-1-i]);
}
void add(Num &a,Num &b)
{
Reverse(a);
int sub = a.back - b.back;
int max_loc = max(sub+b.len,a.len);
memset(a.num + a.len, '0', max_loc - a.len + 1);
for(int i = sub;i < max_loc ;i++)
{
if(a.num[i]=='.')
continue;
int loc_b = b.len-1 - (i-sub);
if(loc_b >= 0)
a.num[i] += b.num[loc_b] - '0';
if(a.num[i] > '9')
{
a.num[i+1]=='.' ? a.num[i+2]++ : a.num[i+1]++;
a.num[i] -= 10;
}
}
int min_loc;
for( min_loc=0; a.num[min_loc]=='0'; min_loc++);
max_loc = a.num[max_loc]=='0' ? max_loc-1 : max_loc;
min_loc = a.num[min_loc]=='.' ? min_loc+1 : min_loc;
for(int i= max_loc;i >= min_loc;i--)
putchar(a.num[i]);
printf("\n");
}[
int main()
{
while(~scanf("%s%s",A.num,B.num))
{
Init(A);
Init(B);
A.back > B.back ? add(A,B) : add(B,A);
}
return 0;
}

代码网上找的,就是有一点不明白。add相加时间。为什么从i=sub开始。
void add(Num &a,Num &b)  
{
Reverse(a);
int sub = a.back - b.back;
int max_loc = max(sub+b.len,a.len);
memset(a.num + a.len, '0', max_loc - a.len + 1);
for(int i = sub;i < max_loc ;i++)
{
if(a.num[i]=='.')
continue;
int loc_b = b.len-1 - (i-sub);
if(loc_b >= 0)
a.num[i] += b.num[loc_b] - '0';
if(a.num[i] > '9')
{
a.num[i+1]=='.' ? a.num[i+2]++ : a.num[i+1]++;
a.num[i] -= 10;
}
}
int min_loc;
for( min_loc=0; a.num[min_loc]=='0'; min_loc++);
max_loc = a.num[max_loc]=='0' ? max_loc-1 : max_loc;
min_loc = a.num[min_loc]=='.' ? min_loc+1 : min_loc;
for(int i= max_loc;i >= min_loc;i--)
putchar(a.num[i]);
printf("\n");
}
...全文
122 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2013-10-21
  • 打赏
  • 举报
回复
仅供参考
#include <stdio.h>
#include <string.h>
#define MAXLEN 1000
char a1[MAXLEN];
char a2[MAXLEN];
static int v1[MAXLEN];
static int v2[MAXLEN];
static int v3[MAXLEN];
int i,j,n,L,z;
void main(void) {
    scanf("%d",&n);
    for (j=0;j<n;j++) {
        scanf("%s%s",a1,a2);

        L=strlen(a1);
        for (i=0;i<L;i++) v1[i]=a1[L-1-i]-'0';

        L=strlen(a2);
        for (i=0;i<L;i++) v2[i]=a2[L-1-i]-'0';

        for (i=0;i<MAXLEN;i++) v3[i]=v1[i]+v2[i];

        for (i=0;i<MAXLEN;i++) {
            if (v3[i]>=10) {
                v3[i+1]+=v3[i]/10;
                v3[i]=v3[i]%10;
            }
        }

        printf("Case %d:\n", j+1);
        printf("%s + %s = ", a1, a2);

        z=0;
        for (i=MAXLEN-1;i>=0;i--) {
            if (z==0) {
                if (v3[i]!=0) {
                    printf("%d",v3[i]);
                    z=1;
                }
            } else {
                printf("%d",v3[i]);
            }
        }
        if (z==0) printf("0");

        printf("\n");
    }
}
//Sample Input
//3
//0 0
//1 2
//112233445566778899 998877665544332211
//
//Sample Output
//Case 1:
//0 + 0 = 0
//Case 2:
//1 + 2 = 3
//Case 3:
//112233445566778899 + 998877665544332211 = 1111111111111111110

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧