大数(高精度)加法

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
思路:模拟整数大数加法,分开小数点前面的和后面的来做

//NYOJ513 已通过
#include <stdio.h>
#include <string.h>
#define MAX 10000
int main()
{
    char a[MAX], b[MAX], c[MAX+1] = {0}, d[MAX+1] = {0};
    int i, lena, lenb, len, flag, flaga, flagb, ia, ib, indexa, indexb, index;
    while(scanf("%s %s", a, b) != EOF)
    {
        getchar();
        lena = strlen(a);
        lenb = strlen(b);
        flaga = flagb = 0;
        for(i = 0; i < lena; i++)//判断是否a串有小数点
        {
            if(a[i] == '.')
            {
                flaga = 1;
                indexa = i;
                break ;
            }
        }
        for(i = 0; i < lenb; i++)//判断是否b串有小数点
        {
            if(b[i] == '.')
            {
                flagb = 1;
                indexb = i;
                break ;
            }
        }
        if(flaga == 0 && flagb == 0)//如果a和b都没有小数点
        {
            len = (lena > lenb) ? lena : lenb;//模拟大数乘法,看看哪一个比较长,就把长度赋给结果数组
            flag = 0;
            for(ia = lena-1, ib = lenb-1, i = len-1; ia >= 0 && ib >= 0; ia--, ib--, i--)
            {//逐个相加,注意进位
                c[i] = (a[ia] - '0' + b[ib] - '0' + flag) % 10 + '0';
                flag = (a[ia] - '0' + b[ib] - '0' + flag) / 10;
            }
            for(; ia >= 0; ia--, i--)
            {//如果a没有加完继续
                c[i] = (a[ia] - '0' + flag) % 10 + '0';
                flag = (a[ia] - '0' + flag) / 10;
            }
            for(; ib >= 0; ib--, i--)
            {//如果b没有加完继续
                c[i] = (b[ib] - '0' + flag) % 10 + '0';
                flag = (b[ib] - '0' + flag) / 10;
            }
            while(flag != 0)
            {//如果最后又进位继续
                for(i = len; i > 0; i--)
                    c[i] = c[i-1];
                c[0] = flag % 10 + '0';
                len++;
                flag /= 10;
            }
            printf("%s\n", c);
        }
        if(flaga == 0 && flagb == 1)
        {
            len = (lena > indexb) ? lena : indexb;
            flag = 0;
            for(i = len-1, ia = lena-1, ib = indexb-1; ia >= 0 && ib >= 0; ia--, ib--, i--)
            {
                c[i] = (a[ia] - '0' + b[ib] - '0' + flag) % 10 + '0';
                flag = (a[ia] - '0' + b[ib] - '0' + flag) / 10;
            }
            for(; ia >= 0; ia--, i--)
            {
                c[i] = (a[ia] - '0' + flag) % 10 + '0';
                flag = (a[ia] - '0' + flag) / 10;
            }
            for(; ib >= 0; ib--, i--)
            {
                c[i] = (b[ib] - '0' + flag) % 10 + '0';
                flag = (b[ib] - '0' + flag) / 10;
            }
            while(flag != 0)
            {
                for(i = len; i > 0; i--)
                    c[i] = c[i-1];
                c[0] = flag % 10 + '0';
                len++;
                flag /= 10;
            }
            printf("%s", c);
            index = lenb-1;
            flag = 0;
            for(i = lenb-1; i > indexb; i--)
            {//最后直接输出小数点即可,只是要注意最后0的处理
                if(b[i] !='0')
                {
                    index = i;
                    flag = 1;
                    break ;
                }
            }
            if(flag == 1)
                for(i = indexb; i <= index; i++)
                    printf("%c", b[i]);
            printf("\n");
        }
        if(flaga == 1 && flagb == 0)
        {
            len = (indexa > lenb) ? indexa : lenb;
            flag = 0;
            for(i = len-1, ia = indexa-1, ib = lenb-1; ia >= 0 && ib >= 0; ia--, ib--, i--)
            {
                c[i] = (a[ia] - '0' + b[ib] - '0' + flag) % 10 + '0';
                flag = (a[ia] - '0' + b[ib] - '0' + flag) / 10;
            }
            for(; ia >= 0; ia--, i--)
            {
                c[i] = (a[ia] - '0' + flag) % 10 + '0';
                flag = (a[ia] - '0' + flag) / 10;
            }
            for(; ib >= 0; ib--, i--)
            {
                c[i] = (b[ib] - '0' + flag) % 10 + '0';
                flag = (b[ib] - '0' + flag) / 10;
            }
            if(flag != 0)
            {
                for(i = len; i > 0; i--)
                    c[i] = c[i-1];
                c[0] = flag % 10 + '0';
                len++;
                flag /= 10;
            }
            printf("%s", c);
            index = lena-1;
            flag = 0;
            for(i = lena-1; i > indexa; i--)
            {
                if(a[i] != '0')
                {
                    index = i;
                    flag = 1;
                    break ;
                }
            }
            if(flag == 1)
            {
                for(i = indexa; i <= index; i++)
                    printf("%c", a[i]);
            }
            printf("\n");
        }
        if(flaga == 1 && flagb == 1)
        {
            len = (lena-indexa < lenb-indexb) ? (lena-indexa) : (lenb-indexb);
            flag = 0;
            for(i = len-2, ia = indexa+len-1, ib = indexb+len-1; ia > indexa && ib > indexb; ia--, ib--, i--)
            {//先算小数点后面的,注意进位
                d[i] = (a[ia] - '0' + b[ib] - '0' + flag) % 10 + '0';
                flag = (a[ia] - '0' + b[ib] - '0' + flag) / 10;
            }
            for(ia = indexa+len, i = len-1; ia < lena; i++, ia++)
                d[i] = a[ia];
            for(ib = indexb+len, i = len-1; ib < lenb; i++, ib++)
                d[i] = b[ib];
            len = (indexa > indexb) ? indexa : indexb;
            for(i = len-1, ia = indexa-1, ib = indexb-1; ia >= 0 && ib >= 0; ia--, ib--, i--)
            {
                c[i] = (a[ia] - '0' + b[ib] - '0' + flag) % 10 + '0';
                flag = (a[ia] - '0' + b[ib] - '0' + flag) / 10;
            }
            for(; ia >= 0; ia--, i--)
            {
                c[i] = (a[ia] - '0' + flag) % 10 + '0';
                flag = (a[ia] - '0' + flag) / 10;
            }
            for(; ib >= 0; ib--, i--)
            {
                c[i] = (b[ib] - '0' + flag) % 10 + '0';
                flag = (b[ib] - '0' + flag) / 10;
            }
            while(flag != 0)
            {
                for(i = len; i > 0; i--)
                    c[i] = c[i-1];
                c[0] = flag % 10 + '0';
                flag /= 10;
                len++;
            }
            printf("%s", c);
            index = strlen(d)-1;
            flag = 0;
            for(i = strlen(d)-1; i >= 0; i--)
            {
                if(d[i] != '0')
                {
                    index = i;
                    flag = 1;
                    break ;
                }
            }
            if(flag == 1)
            {
                printf(".");
                for(i = 0; i <= index; i++)
                    printf("%c", d[i]);
            }
            printf("\n");
        }
        memset(a, 0, MAX);
        memset(b, 0, MAX);
        memset(d, 0, MAX+1);
        memset(c, 0, MAX+1);
    }
    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值