高精度寄算

高精度计算

由于创建的变量存在空间大小的限制,若数字的位数过大,可能无法进行计算,甚至无法创建相应变量。 因此借助数组将数字的每一位单独储存,并以小学所学的竖式计算为原理进行运算。最后的结果也以数组进行储存。

输入

输入的时候,要倒序储存,以便进位。 同时用数组的第一位来储存该数的位数,便于随时调用。

1
2
3
4
5
6
7
8
void init(int a[])
{
    string s;
    cin>>s;
    a[0] = s.length();
    for (int i=1; i<=a[0]; i++)
        a[i] = s[a[0]-i] - 48;
}

输出

注意倒序输出

1
2
3
4
5
6
void print(int a[])
{
    for (int i=a[0]; i>0; i--)
        printf("%d",a[i]);
    cout<<endl;
}

加法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
void add(int a[],int b[])
{
    int i=1,x=0; //i为当前计算的位数,x为向下一位的进位 
    while (i<=len1 || i<=len2) //len为两个数字的位数,要满足两者的每一位均进入计算过程 
    {
        c[i]=a[i]+b[i]+x;
        x=c[i]/10; //处理进位 
        c[i]%=10;
        i++;
    }
    if (x == 0) //最高位特判 
    {
        len3=i-1;
        return;
    }
    c[i]=x;
    len3=i;
}

减法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void minuss(char S1[],char S2[])
{
    char S3[num]; 
    if (strlen(S1)<strlen(S2) || (strlen(S1) == strlen(S2) && strcmp(S1,S2)<0)) //strcmp()用于比较字符串大小,原理为将两个字符串同位上的字符进行ASCLL码相减,若为0则将下一位相减,结果不为0时返回相减所得值,若字符串相等则返回0.
    {
        strcpy(S3,S1); //strcpy()将函数中的后一个数组的值完全赋值给前一个数组 
        strcpy(S1,S2);
        strcpy(S2,S3);
        cout<<"-";
    } 
    len1=strlen(S1);
    len2=strlen(S2);
    for (int i=0;i<=len1-1;i++) //逆序存入int数组,便于计算 
        a[len1-i]=int(S1[i]-48); //S1的指针从0开始,a的指针从1开始 
    for (int i=0;i<=len2-1;i++)
        b[len2-i]=int(S2[i]-48);
    int w=1;
    while (w<=len1 || w<=len2)
    {
        if (a[w]<b[w]) //不够减的话向高位借1 
        {
            a[w]+=10;
            a[w+1]--;
        }
        ans[w]=a[w]-b[w];
        w++;
    }
    lena=w;
    while ((ans[lena] == 0) && lena > 1) lena--;
    for (int i=lena;i>=1;i--) //注意倒序输出最后是i-- 
        printf("%d",ans[i]);
    return;
}

乘法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
void chen(int a1[],int a2[])
{
    for (int i=1;i<=len1;i++)
    {
        int jw=0; //处理进位 
        for (int j=1;j<=len2;j++)
        {
            ans[i+j-1]=ans[i+j-1]+a1[i]*a2[j]+jw; //例如6*6=36中,第一步是确定个位上的6,再将3进位 
            jw=ans[i+j-1]/10;
            ans[i+j-1]%=10; //注意每一位上的数字要小于10 
        }
        ans[i+len2]+=jw;
    }
    ans[0]=len1+len2; //多位数乘多位数,结果的位数不会超过两数位数之和 
    while (ans[0] >= 1 && ans[ans[0]] == 0) ans[0]--; //日常抹零 
}

高精除以低精

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
void dichu(int a[],int b)
{
    int x=0;
    for (int i=1; i<=a[0]; i++)
    {
         ans[i] = (x * 10 + a[i]) / b;
        x = (x * 10 + a[i]) % b;
    }
    int ans[0] = 1;
    while (ans[ans[0]] == 0 && ans[0] <= lens)
        ans[0]++;
}

高精除以高精

重中之重,并且是难点。 cop函数用于比较两个高精度数据的大小。 jian函数是正常的高精度减法。 gc函数是主体函数,主要思想是以减法来模拟除法,从而实现计算。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
int cop(int a[],int b[])
{
    if (a[0] < b[0]) return -1;
    else if (a[0] > b[0]) return 1;
    else
    {
        for (int i=a[0]; i>0; i--)
        {
            if (a[i] > b[i]) return 1;
            else if (a[i] < b[i]) return -1;
        }
        return 0;
    }
}

void jian(int a[],int b[])
{
    int flag;
    flag = cop(a,b);
    if (flag == 0)
    {
        a[0] = 0;
        return;
    }
    else if (flag == 1)
    {
        for (int i=1; i<=b[0]; i++)
        {
            if (a[i] < b[i])
            {
                a[i+1]--;
                a[i] += 10;
            }
            a[i] -= b[i];
        }
        while (a[0] > 0 && a[a[0]] == 0) a[0]--;
    }
    return;
}

void gc(int a[],int b[],int c[])
{
    if (cop(a,b) == -1)
    {
        printf("0\n");
        print(a);
    }
    else
    {
        int tmp[num];
        c[0] = a[0] - b[0] + 1;
        for (int i=c[0]; i>0; i--)
        {
            memset(tmp,0,sizeof(tmp));
            for (int j=1; j<=b[0]; j++)
                tmp[i+j-1] = b[j];
            tmp[0] = b[0] + i - 1;
            while (cop(a,tmp) != -1)
            {
                c[i]++;
                jian(a,tmp);
            }
        }
        while (c[0] > 0 && c[c[0]] == 0) c[0]--;
    }
    return;
}
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
主题 StackJimmy 设计