其他分享
首页 > 其他分享> > 高精度运算总结

高精度运算总结

作者:互联网

日期:2022年5月18日

注:本博客中的代码仅供参考。


 

概念

数据类型 定义标识符 数据范围
整型 int -231~231-1(≈2×109
长整型 long long -263~263-1
无符号长整型 unsigned long long 0~264-1

上面给出的范围的数称为单精度数,对应的运算称为单精度运算。

超出上面给出的范围的数称为高精度数(注:尝试使用这些范围存储的话会导致溢出),对应的运算称为高精度运算。

实现方法

将输入的数字导入某一数组(注:不同的数需要导入不同数组),并在该数组中模拟计算过程,最后将数组中的数字输出。

注:数组中的每一个位置应只存储一个位数的数字,否则在输出时可能会出现问题。

代码(正片【确信】)

高精度加法

#include<bits/stdc++.h>
using namespace std;
char s[510];//这个字符数组作为数据的“中转站”,最终将数据导入数组中
struct bigInt{
    int length;//数据的长度(位数)
    int v[510];//存储数据的数组
};
bigInt operator +(bigInt a,bigInt b){//重新载入+
    int k=max(a.length,b.length);//比较尾数大小,将更大的位数作为之后相加的长度
    for(int i=1;i<=k;++i)
    {
        a.v[i]+=b.v[i];//将每一位的数相加
    }
    for(int i=1;i<=k;++i)//进位
    {
        a.v[i+1]+=a.v[i]/10;
        a.v[i]%=10;
    }
    if(a.v[k+1])
    {
        ++k;
    }//如果最高位也存在进位,增加k的长度
  //严格来说,应该检查不止一位。但因为加法最多会增加一位,所以检查与否都无足轻重,然而在高精度乘法中会显得尤为必要
    a.length=k;
    return a;
}
bigInt A,B;
int main(){
    scanf("%s",s+1);//输入数据。s+1代表数据从s[1]向后存储
    int n=strlen(s+1);//求数据的位数
    for(int i=1;i<=n;++i)
    {
        A.v[i]=s[n-i+1]-'0';//赋值。-'0'可以使数据从字符转化为数字。倒过来存储有利于后面的计算(尤其是出现最高位进位时)
    }
    A.length=n;//赋值
    scanf("%s",s+1);
    n=strlen(s+1);
    for(int i=1;i<=n;++i)
    {
        B.v[i]=s[n+1-i]-'0';
    }
    B.length=n;
    A=A+B;//相加。这里的+使用的是重新载入的+
    for(int i=A.length;i>=1;--i)
    {
        printf("%d",A.v[i]);//输出求得的和。由于数据是倒过来存储的,输出也应倒过来输出
    }
    return 0;
}

高精度减法

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=10186;
 4 struct bigInt{
 5     int length;
 6     int v[N];
 7 };
 8 bigInt A,B,C;
 9 char s[N];
10 bigInt read(){//用于读入数据的函数
11     memset(C.v,0,sizeof(C.v));
12     scanf("%s",s+1);
13     int n=strlen(s+1);
14     for(int i=1;i<=n;++i)
15     {
16         C.v[i]=s[n+1-i]-'0';
17     }
18     C.length=n;
19     return C;
20 }
21 bool operator >=(bigInt a,bigInt b){//比较两数大小
22     int m=a.length;
23     int n=b.length;
24     if(m>n)//当m与n位数不同时,位数更大的数更大
25     {
26         return true;
27     }
28     if(m<n)
29     {
30         return false;
31     }
32     for(int i=n;i>0;--i)
33     {
34         if(a.v[i]>b.v[i])//当位数相同时,从最高位向下遍历。如果某个数的某一位数字更大,则这个数更大
35         {
36             return true;
37         }
38         if(a.v[i]<b.v[i])
39         {
40             return false;
41         }
42     }
43     return true;
44 }
45 bigInt operator -(bigInt a,bigInt b){
46     int k=a.length;
47     for(int i=1;i<=k;++i)
48     {
49         if(a.v[i]<b.v[i])
50         {
51             --a.v[i+1];
52             a.v[i]+=10;
53         }
54         a.v[i]-=b.v[i];
55     }
56     while(a.v[k]==0&&k>1)
57     {
58         --k;
59     }
60     a.length=k;
61     return a;
62 }
63 int main(){
64     A=read();
65     B=read();
66     if(A>=B)
67     {
68         A=A-B;
69     }else{
70         printf("-");
71         A=B-A;
72     }//都是大的数减小的数,如果A<B时,在输出数据前面输出-
73     for(int i=A.length;i>0;--i)
74     {
75         printf("%d",A.v[i]);
76     }//同理,倒过来输出
77     return 0;
78 } 

高精度乘法

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 char s[2500];
 4 int result[4005]={0},rlength;
 5 struct bigInt{
 6     int length;
 7     int v[2500];
 8 };
 9 bigInt operator *(bigInt a,bigInt b){
10     for(int i=1;i<=a.length;++i)
11     {
12         for(int j=1;j<=b.length;++j)
13         {
14             result[i+j-1]+=a.v[i]*b.v[j];
15         }
16     }
17     for(int i=1;i<=4001;++i)
18     {
19         result[i+1]+=result[i]/10;
20         result[i]%=10;
21     }
22     rlength=a.length+b.length;
23     while(result[rlength]==0&&rlength>1)
24     {
25         --rlength;
26     }//乘法最高位可能不止进一位,但因为所得结果的最多位数为A的位数,B的位数,可以从最多位数开始向后遍历,在遇到不为0的数前且位数不为1时(考虑到结果为0的情况),将估计位数缩减
27 }
28 bigInt A,B;
29 int main(){
30     scanf("%s",s+1);
31     int n=strlen(s+1);
32     for(int i=1;i<=n;++i)
33     {
34         A.v[i]=s[n+1-i]-'0';
35     }
36     A.length=n;
37     scanf("%s",s+1);
38     n=strlen(s+1);
39     for(int i=1;i<=n;++i)
40     {
41         B.v[i]=s[n+1-i]-'0';
42     }
43     B.length=n;
44     A=A*B;
45     for(int i=rlength;i>=1;--i)
46     {
47         printf("%d",result[i]);
48     }
49     return 0;
50 }

高精度除法

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=5100;
 4 struct bigInt{
 5     int length;
 6     int v[N];
 7 };
 8 bigInt operator /(bigInt a,long long b){
 9     int k=a.length;
10     long long res=0,c=0;
11     for(int i=k;i>=1;--i)//因为除法在计算时与+、-、×相反,且数据存储时依然是倒过来存储的,所以此处要从最高位开始运算
12     {
13         res=res*10+a.v[i];
14         a.v[i]=res/b;
15         res%=b;
16     /*这里的原理是:
17     ①余数(res)乘10并加上下一位
18     ②将余数整除10的结果赋给要参加运算的那一位
19     ③余数取余10
20     */
21     }
22     while(a.v[k]==0&&k>1)
23     {
24         --k;//统计位数
25     }
26     a.length=k;
27     return a;
28 }
29 bigInt A;
30 long long B;
31 char s[N];
32 int main(){
33     scanf("%s",s+1);
34     int n=strlen(s+1);
35     for(int i=1;i<=n;++i)
36     {
37         A.v[i]=s[n+1-i]-'0';
38     }
39     A.length=n;
40     scanf("%lld",&B);
41     A=A/B;
42     for(int i=A.length;i>=1;--i)
43     {
44         printf("%d",A.v[i]);
45     }
46     return 0;
47 } 

 


一些心得

 

标签:总结,运算,高精度,int,res,long,--,length,bigInt
来源: https://www.cnblogs.com/PlayerSS05/p/16286352.html