为啥要高精度算法,如果有一个数很大比如10的100次方,很明显计算机不能存储这么大的数。那么我们可以采用高精度算法。利用数组和字符串来计算。
1.高精度加法
#include <iostream>
#include <cmath>
using namespace std;
string a,b;
int as[100000],bs[100000],c[100001];
int main(){
cin>>a>>b; //以字符串形式输入
int len1=a.size();
int len2=b.size();
for(int i=0;i<len1;i++){
as[len1-1-i]=a[i]-'0'; //反转,小位在前面
}
for(int i=0;i<len2;i++){
bs[len2-1-i]=b[i]-'0';
}
int len=max(len1,len2);
for(int i=0;i<len;i++){
c[i]=c[i]+as[i]+bs[i]; //高精度核心加法算法
c[i+1]=c[i]/10;
c[i]=c[i]%10;
}
len+=1;
if(c[len-1]==0&&len>1){
len-=1;
}
for(int i=0;i<len;i++){
cout<<c[len-1-i]; //先输出高位
}
return 0;
}
2.高精度减法
#include <iostream>
#include <cmath>
using namespace std;
string a,b;
int as[100005],bs[100005],c[1000006];
int main(){
cin>>a>>b;
int len1=a.size();
int len2=b.size();
for(int i=0;i<len1;i++){
as[len1-i-1]=a[i]-'0'; // 反转
}
for(int i=0;i<len2;i++){
bs[len2-i-1]=b[i]-'0';
}
int len=max(len1,len2);
for(int i=0;i<len;i++){
if(as[i]<bs[i]){
as[i+1]-=1;
as[i]+=10;
}
c[i]=as[i]-bs[i];
}
while(c[len-1]==0 && len>1){
len-=1;
}
for(int i=0;i<len;i++){
cout<<c[len-1-i];
}
return 0;
}
只支持a,b为正数且,a>b时
3.高精度乘法
#include <iostream>
#include <cmath>
using namespace std;
int as[100000],bs[100000],c[100005];
string a,b;
int main(){
cin>>a>>b; //输入字符串
int len1=a.size();
int len2=b.size();
for(int i=0;i<len1;i++){
as[len1-1-i]=a[i]-'0';
}
for(int i=0;i<len2;i++){
bs[len2-1-i]=b[i]-'0';
}
for(int i=0;i<len1;i++){
for(int j=0;j<len2;j++){
c[i+j]+=as[i]*bs[j];
c[i+j+1]+=c[i+j]/10;
c[i+j]%=10;
}
}
int len=len1+len2;
while(c[len-1]==0 && len>1){
len-=1;
}
for(int i=0;i<len;i++){
cout<<c[len-i-1];
}
return 0;
}
4.高精度除法(高精除低精)
底板除,无论小数多少,都省略
#include <iostream>
using namespace std;
string a;
int b;
int as[100005],c[100005];
int main(){
cin>>a>>b;
int len1=a.size();
for(int i=0;i<len1;i++){
as[i]=a[i]-'0';
}
long long rem=0;
for(int i=0;i<len1;i++){
c[i]=(rem*10+as[i])/b;
rem=(rem*10+as[i])%b; //这一位除数
}
long long s=0; //从前面开始去0
while(c[s]==0 && s<len1){
s++;
}
for(int i=s;i<len1;i++){
cout<<c[i];
}
return 0;
}
例题:
题目描述
用高精度计算出 S=1!+2!+3!+⋯+n!(n≤50)。
其中 !
表示阶乘,定义为 n!=n×(n−1)×(n−2)×⋯×1。例如,5!=5×4×3×2×1=120。
输入格式
一个正整数 n。
输出格式
一个正整数 S,表示计算结果。
输入输出样例
输入 #1复制
3
输出 #1复制
9
说明/提示
【数据范围】
对于 100% 的数据,1≤n≤50。
这道题简单吧,说实话得分容易,得满分不容易,比如50的阶乘计算机能算出来吗?所以这道题比较麻烦,用高精度加法和高精度乘法;
#include <iostream>
#include <cmath>
using namespace std;
int n;
int a[55];
string cheng(string a,string b){
int as[20000]={0},bs[20000]={0},c[20000]={0};
int len1=a.size();
int len2=b.size();
for(int i=0;i<len1;i++){
as[len1-1-i]=a[i]-'0';
}
for(int i=0;i<len2;i++){
bs[len2-1-i]=b[i]-'0';
}
for(int i=0;i<len1;i++){
for(int j=0;j<len2;j++){
c[i+j]+=as[i]*bs[j];
c[i+j+1]+=c[i+j]/10;
c[i+j]%=10;
}
}
int len=len1+len2;
while(c[len-1]==0 && len>1){
len-=1;
}
string ans="";
for(int i=0;i<len;i++){
ans+=(char)(c[len-i-1]+'0');
}
return ans;
}
string jia(string a,string b){
int as[200]={0},bs[200]={0},c[200]={0};
int len1=a.size();
int len2=b.size();
for(int i=0;i<len1;i++){
as[len1-i-1]=a[i]-'0';
}
for(int i=0;i<len2;i++){
bs[len2-i-1]=b[i]-'0';
}
int len=max(len1,len2);
for(int i=0;i<len;i++){
c[i]=c[i]+as[i]+bs[i];
c[i+1]=c[i]/10;
c[i]=c[i]%10;
}
len+=1;
if(c[len-1]==0 && len>1){
len--;
}
string ans="";
for(int i=0;i<len;i++){
ans+=(char)(c[len-i-1]+'0');
}
return ans;
}
string zhuan(int x){
string a="";
while(x){
a+=(x%10)+'0';
x=x/10;
} //int 转为string类型
int c=a.size();
string b="";
for(int i=c-1;i>=0;i--){
b+=a[i];
}
return b;
}
string jie(string x,int xx){
string ans=x;
if(ans=="1"){
return "1";
}
for(int i=1;i<xx;i++){
string g=zhuan(i);
ans=cheng(ans,g);
}
return ans;
}
string m[10000];
string ans;
int main(){
cin>>n;
for(int i=0;i<n;i++){
a[i]=i+1;
}
for(int i=0;i<n;i++){
string v=zhuan(a[i]); //转为string类型;
m[i]=jie(v,a[i]);
}
for(int i=0;i<n;i++){
ans=jia(ans,m[i]);
}
cout<<ans;
return 0;
}