高精度算法

给你一囗甜甜゛ 提交于 2019-11-27 09:46:20

虽然这玩意就是在考代码量qwq,但老是考还是要整理总结下。

一,什么是高精度

我们知道Int,longlong等都有一个最大精度,比如int 2147483647,有时我们需要计算的整形数字大小超过了longlong的精度,

所以我们就要用高精度进行计算。

二,高精度数的存储

通常我们用数组存储高精度数的每一位。

一般a[0]存储的是这个高精度数的位数。

a[1]存储的是这个这个高精度数的个位。

a[a[0]]存储的是这个高精度数的最高位。

读入方法:

 

inline void init(int a[])
{
    char s[10005];
    cin>>s;
    a[0]=strlen(s);
    for(int i=1;i<=a[0];i++)
        a[i]=s[a[0]-i]-'0';
    return;
}
View Code

 

三,高精度加法

高精度计算的精髓在于模拟数学中的竖式,高精度加法模拟的就是竖式的加法运算。

我们设要计算的两个数组分别为a和b,结果存到数组c中。

加法就需要进位,如果某一位c[i]=a[i]+b[i]>=10了,那么c[i+1]++;c[i]-=10;

注意高精度计算常常要处理前导零。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 int numa[1005],numb[1005],ans[1005];
 9 
10 inline void init(int a[])
11 {
12     char s[1005];
13     scanf("%s",s);
14     a[0]=strlen(s);
15     for(int i=1;i<=a[0];i++)
16         a[i]=s[a[0]-i]-'0';
17     return;
18 }
19 
20 int main()
21 {
22     init(numa);
23     init(numb);
24     int len=max(numa[0],numb[0]);
25     for(int i=1;i<=len;i++)
26     {
27         ans[i]+=numa[i]+numb[i];
28         ans[0]++;
29         if(ans[i]>=10)
30         {
31             if(i==len) ans[0]++;
32             ans[i+1]++;
33             ans[i]-=10;
34         }
35     }
36     while(ans[0]>1&&ans[ans[0]]==0) ans[0]--;
37     for(int i=ans[0];i>=1;i--)
38         printf("%d",ans[i]);
39     return 0;
40 }
高精度加法

四,高精度减法

类似于高精度加法,借助了竖式运算,注意高精度减法中,被减数一定要比减数大,所以要先判断哪个比较大。

 

和高精度加法完全相同的输入,计算时  如果a[i]<b[i],就借一位,a[i+1]- -;a[i]+=10;

 

注意处理前导零。

 

高精度减法

 

五,高精度乘法

乘法 ans[i+j-1]+=numa[i]*num[j];不理解可以写一下竖式。

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

int numa[50001],numb[50001],ans[50001];

inline void init(int a[])
{
    char s[2005];
    scanf("%s",s);
    a[0]=strlen(s);
    for(int i=1;i<=a[0];i++)
        a[i]=s[a[0]-i]-'0';
    return;
}

int main()
{
    init(numa); init(numb);
    for(int i=1;i<=numa[0];i++)
        for(int j=1;j<=numb[0];j++)
            ans[i+j-1]+=numa[i]*numb[j];
    int len=numa[0]+numb[0];
    for(int i=1;i<=len;i++)
        if(ans[i]>=10)
        {
            ans[i+1]+=ans[i]/10;
            ans[i]%=10;
        }
    while(len>1&&ans[len]==0) len--;
    for(int i=len;i>=1;i--)
        printf("%d",ans[i]);
    return 0;
} 
View Code

 

六,高精度除以低精度(整除)

模仿竖式一位一位进行除法

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

int numa[2333],numb,x,ans[2333];

inline void init(int a[])
{
    char s[2333];
    scanf("%s",s);
    a[0]=strlen(s);
    for(int i=1;i<=a[0];i++)
        a[i]=s[a[0]-i]-'0';
    return;
}

int main()
{
    init(numa);
    scanf("%d",&numb);
    for(int i=numa[0];i>=1;i--)
    {
        ans[i]=(x*10+numa[i])/numb;
        x=(x*10+numa[i])%numb;
    }
    ans[0]=numa[0];
    while(ans[0]>1&&ans[ans[0]]==0) ans[0]--;
    for(int i=ans[0];i>=1;i--)
        printf("%d",ans[i]);
    return 0;
}
高精度除以低精度

 

 

 

 

 

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!