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

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

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

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


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

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

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


虽然很水还是看道题吧

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

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

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

//把主要计算操作处理完之后,再处理进位并得到答案
#include
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
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时才开始输出。

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

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

你可能感兴趣的:(一些总结,数学)