参考:
(48条消息) 大数(加、减、乘、除、低精度*大数)模板详解(C++)_氵青-风的博客-CSDN博客_c++ 大数
模板:
1 //大数加,减,乘,除,阶乘(低精度*大数)
2 //大数
3 #include<bits/stdc++.h>
4 #include<cstring>
5 using namespace std;
6 //初始化,补全位数
7 void inital(string &a,string &b)
8 {
9 while(a.size()<b.size()) a='0'+a;
10 while(b.size()<a.size()) b='0'+b;
11 }
12 //找最大值,使a>b
13 void findmax(string &a,string &b)
14 {
15 string cmp;
16 if(a<b)
17 {
18 cmp=a;
19 a=b;
20 b=cmp;
21 }
22 }
23 //删除第一个'0'
24 bool del(string &a)
25 {
26 if(a[0]=='0')
27 {
28 a.erase(0,1);
29 return true;
30 }
31 else
32 return false;
33 }
34 //删除全部的'0',基于del
35 void delall(string &a)
36 {
37 while(del(a))
38 {
39 del(a);
40 }
41 }
42 //大数加法
43 string bigadd(string a,string b)
44 {
45 inital(a,b);//初始化,先补位,使a,b对齐
46 //a,b前都加一个'0'方便进位(例如三位数加三位数最多为四位数)
47 a='0'+a;
48 b='0'+b;
49 //从后往前,按位加
50 for(int i=a.size()-1;i>=0;i--)
51 {
52 //减'0'的ASCII码,得到准确数据
53 int num1=a[i]-'0';
54 int num2=b[i]-'0';
55 //如果相加大于10,进位
56 if(num1+num2>9)
57 {
58 a[i-1]=a[i-1]-'0'+1+'0';
59 a[i]=num1+num2-10+'0';
60 }
61 else
62 {
63 a[i]=num1+num2+'0';
64 }
65 }
66 //删除最前面的'0'
67 del(a);
68 //cout<<a<<endl;
69 return a;
70 }
71 //大数减法,基本与大数加法相同
72 string bigsub(string a,string b)
73 {
74 inital(a,b);
75 //找到a,b中的最大值,来分别充当减数与被减数
76 findmax(a,b);
77 for(int i=a.size()-1;i>=0;i--)
78 {
79 int num1=a[i]-'0';
80 int num2=b[i]-'0';
81 //被减数小于减少,进行借位
82 if(num1<num2)
83 {
84 a[i-1]=a[i-1]-'0'-1+'0';
85 a[i]=(num1+10-num2)+'0';
86 }
87 else
88 {
89 a[i]=num1-num2+'0';
90 }
91 }
92 //删除a前面全部的'0'
93 delall(a);
94 cout<<a<<endl;
95 return a;
96 }
97 //大数乘法,基于大数加法
98 void bigmul(string a,string b)
99 {
100 //先考虑特殊情况
101 //删除a,b前面所有的零,若其中一个为空,表示其中一个乘数为0,那么a*b=0
102 delall(a);
103 delall(b);
104 if(a==""||b=="")
105 {
106 cout<<"0"<<endl;
107 return;
108 }
109 //考虑完特殊情况后初始化a,b
110 inital(a,b);
111 //找到a,b中的最大值,把问题转化为大数加分
112 findmax(a,b);
113 string res="0";//存储答案
114 delall(b);//删除b前所有的'0',把b拆分充当小数
115 for(int i=b.size()-1;i>=0;i--)
116 {
117 int num1=b[i]-'0';
118 //例如:10*5555=1*55550
119 if(i!=b.size()-1)
120 {
121 a=a+'0';
122 }
123 //例如5*10转化为:5个10相加
124 for(int j=1;j<=num1;j++)
125 {
126 res=bigadd(res,a);
127 }
128 }
129 //删除res前所有的'0'
130 delall(res);
131 cout<<res<<endl;
132 }
133 //大数除法,注意每次判断前都要补全
134 //相当于求:被除数是除数的几倍
135 void bigdiv(string a,string b)
136 {
137 inital(a,b);//将要判断a与b的大小关系,需补全
138 //特殊情况
139 if(a<b)
140 {
141 cout<<"0"<<endl;
142 return;
143 }
144 delall(b);
145 string res="0";//存储答案
146 string tmp=b;//存储每次的除数=b*restmp
147 string restmp="1";//倍数
148 for(int i=1;i<=(a.size()-b.size());i++)
149 {
150 //计算a与b相差的位数,即为相差的倍数
151 tmp+='0';
152 restmp+='0';
153 }
154 inital(a,b);//将要进行判断a,b的大小关系,需补全
155 while(a>=b)
156 {
157 inital(a,tmp);//将要判断a,tmp的大小关系,需补全
158 //将除法转化为减法
159 if(a>=tmp)
160 {
161 a=bigsub(a,tmp);//a=a-tmp
162 res=bigadd(res,restmp);//答案加上此时的倍数
163 }
164 else
165 {
166 //a<tmp则/10
167 tmp.erase(tmp.size()-1);
168 restmp.erase(restmp.size()-1);
169 inital(a,tmp);//将要判断a,tmp的大小关系,需补全
170 //将除法转化为减法,同上
171 if(a>=tmp)
172 {
173 a=bigsub(a,tmp);
174 res=bigadd(res,restmp);
175 }
176 }
177 inital(a,b);//将要判断下一轮的a,b大小关系,需补全
178 }
179 cout<<res<<endl;
180 }
181 void fac(int n)
182 {
183 int num[10000];
184 memset(num,0,sizeof(num));
185 num[0]=1;//存储位数
186 num[1]=1;//首位初值为1
187 for(int i=1;i<=n;i++)
188 {
189 int len=num[0];
190 //每一位都乘i
191 for(int j=1;j<=len;j++)
192 {
193 num[j]*=i;
194 }
195 for(int k=1;k<=num[0];k++)
196 {
197 //进位更新num[k]和num[k+1]
198 if(num[k]>9)
199 {
200 num[k+1]+=num[k]/10;
201 num[k]=num[k]%10;
202 }
203 //进位后num[0]++
204 if(num[num[0]+1]!=0)
205 {
206 num[0]++;
207 }
208 }
209 }
210 //遍历
211 for(int i=num[0];i>=1;i--)
212 {
213 cout<<num[i];
214 }
215 cout<<endl;
216 }
217 int main()
218 {
219 string a,b;
220 cin>>a>>b;
221 //bigadd(a,b);
222 //bigsub(a,b);
223 bigmul(a,b);
224 //bigdiv(a,b);
225 //int n;
226 //cin>>n;
227 //fac(n);
228 }
原创文章,作者:3628473679,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/245243.html