【水】高精度下进位的处理方法

本文涉及内容过于水,慎入,勿喷。

记得还在学语法基础的时候,写过一个高精度加法,当时就觉得进位这东西很烦人。最近写了高精度乘法,水了两道低精度累乘得到高精度的题,提高了姿势水平,才发现自己原来是多么菜(虽然现在也是)。

本文主要讨论高精度加法和低精度累乘得到高精度的情况。对于高精度乘高精度的模板,参考另一篇博文:高精度乘法


大体上说,就是从低位到高位进行计算,之后从倒数第二位开始讨论,写成代码大概是这个样子:

//从a[0]开始存各位上的数字
for(int i=1;i<MAXN;i++)//MAXN为这个数的最大位数
{
    a[i]+=a[i-1]/10;
    a[i]%=10;
}

这段代码想法很简单,做法也很显然。使用起来很方便:可以把所有的计算操作弄完之后再通过这样的操作得到答案,也可以一边进行计算操作一边执行上述操作。举个例子:


虽然很水还是看道题吧

输入一个正整数n,求出1到n的阶乘。n<=30

额,除了高精度外一无所有的语法基础题。这就是上面说的“低精度累乘得到高精度”。

注意下面两段代码是等价的:

//把主要计算操作处理完之后,再处理进位并得到答案
#include<stdio.h>
int Ans[100],N;
int main()
{
    int i,j;
    scanf("%d",&N);
    Ans[1]=1;
    for(i=2;i<=N;i++)
    {
        for(j=1;j<100;j++)Ans[j]*=i;
        for(j=1;j<100;j++)
        {
            Ans[j]+=Ans[j-1]/10;
            Ans[j-1]%=10;
        }
    }
    i=99;while(!Ans[i])i--;
    while(i)putchar(Ans[i]+48),i--;
}
//一边执行计算操作,一边处理进位
#include<stdio.h>
int Ans[100],N;
int main()
{
    int i,j;
    scanf("%d",&N);
    Ans[1]=1;
    for(i=2;i<=N;i++)
    {
        for(j=1;j<100;j++)
        {
            Ans[j]*=i;
            Ans[j]+=Ans[j-1]/10;
            Ans[j-1]%=10;
        }
    }
    i=99;while(!Ans[i])i--;
    while(i)putchar(Ans[i]+48),i--;
}

真是水得不能再水了

如果实在有疑问,恐怕和我当初一样,是这样的:

高精度乘法就是在模拟乘法的过程,而竖式中对于两位或更多位的因数,我们是逐位地进行乘法操作,再相加得到最后结果的。这里有两位数参与了高精度乘法运算,却没有按照这样的法则运算,而是直接对每一位上的数乘上了一个两位数,这样做没问题吗?

肯定是没问题的。
以12345*6789为例,可以写成(1*10^4+2*10^3+3*10^2+4*10^1+5*10^0)*6789
用乘法分配律拆出来就可以理解了。


啰嗦一下,读入字符串后用int数组存时,编号小的存低位,方便计算时对齐。输出时从最高位开始讨论,当讨论到的位置不是0时才开始输出。

然而我发现我并没有举高精度加法的例子,反正很水就不举了吧。

为什么我会写这篇文章……我也不知道讲了什么

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值