大数,高精度计算---大数加法

大数是算法语言中的数据类型无法表示的数,其位数超过最大数据类型所能表示的范围,所以,在处理大数问题时首先要考虑的是怎样存储大数,然后是在这种存储方式下其处理的实现方法。

一般情况下大数的存储是采用字符数组来存储,即将大数当作一个字符串来存储,而对其处理是按其处理规则在数组中模拟实现。


一  大数加法。

思路很常规。先用字符数组录入大数,(这个时候高位存在数组下标小的位置。  如:最高位在arr[0]处。  ---输入方式原因)  

然后再从高往低反向存入整数数组中。(使得低位在数组下标小的位置,符合常规。)

然后在进行计算,考虑进位情况。

加法比较简单,就不多说什么了。  直接上代码。


#include <stdio.h>
#include <string.h>
#define MAXLEN 1000

int main()
{
    char a1[MAXLEN];
    char a2[MAXLEN];
    static int v1[MAXLEN];
    static int v2[MAXLEN];
    static int v3[MAXLEN];
    int i,j,n,L,z;

    scanf("%d",&n);      //读入计算的组数
    for (j=0;j<n;j++)
    {
        scanf("%s%s",a1,a2);   //读入每组计算的2个大数

        L=strlen(a1);
        for (i=0;i<L;i++)
            v1[i]=a1[L-1-i]-'0';      //大数a1反向

        L=strlen(a2);
        for (i=0;i<L;i++)
            v2[i]=a2[L-1-i]-'0';   //大数a2反向

        for (i=0;i<MAXLEN;i++)
            v3[i]=v1[i]+v2[i];       //a1.a2各位直接相加,先不考虑进位

        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");
    }
    return 0;
}


其实,上述代码还能进一步简化,合并操作步骤。

可以将大数的颠倒过程和求和运算过程合并,颠倒的过程是逐位移动到整数数组的过程,在移位的过程中,同时实现运算,但此时依旧先不考虑进位,所有各位的进位都在计算完成后统一处理。


#include <stdio.h>
#include <string.h>

int main()
{
    char s[202];    //  假设大数不超过200位。  
    int sum[201];
    int i, j, d, len, maxlen=0;

    for (i=0;i<201;i++)        //对各位和进行初始化
    {
        sum[i] = 0;
    }
    for (i=0;i<2;i++)   // 读入两个大数
    {
        scanf("%s", s);
        len = strlen(s);
        if (len>maxlen)
            maxlen = len;
        for (j=len-1;j>=0;j--)
            sum[len-1-j] += s[j] - '0';         //颠倒求和,存入结果数组sum中
    }

    for (i=0,d=0;i<maxlen;i++)   //从低位开始处理结果中的进位
    {
        sum[i] += d;
        d = sum[i] / 10;
        sum[i] %= 10;
    }

    if (d>0)
        sum[maxlen++] += d;         //如果最后一个有进位,再往前挪一位
    for (i=maxlen-1;i>=0;i--)
        s[maxlen-1-i] = sum[i] + '0';       //结果以字符串方式保存
    s[maxlen] = '\0';
    printf("%s\n",s);         //输出结果

    return 0;
}



加法算法固然简单,也算大数的入门吧。也是有必要提一提的。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Colin丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值