高精度运算板子(包括小数的高精度乘方)
程序员文章站
2022-05-12 15:02:23
...
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
inline bool compare(string a,string b)
{
int i;
///消除前导0
for(i=0;a[i]=='0'&&i<a.size()-1;i++); a=a.substr(i,a.size()-i);
for(i=0;b[i]=='0'&&i<b.size()-1;i++); b=b.substr(i,b.size()-i);
if(a.size()==b.size()) return a>b;
return a.size()>b.size();
}
string add(string a,string b)///高精度加法
{
string c;
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
int carry=0,temp;
for(int i=0;i<a.size()||i<b.size();i++)
{
temp=carry;
if(i<a.size()) temp+=a[i]-'0';
if(i<b.size()) temp+=b[i]-'0';
c.push_back(char(temp%10+'0'));
carry=temp/10;
}
if(carry!=0) c.push_back(char('0'+carry));
reverse(c.begin(),c.end());
int i;
for(i=0;c[i]=='0'&&i<c.size()-1;i++);///消除前导0,但保证至少有一个
c=c.substr(i,c.size()-i);
return c;
}
string sub(string a,string b)///a-b高精度减法
{
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
string c;int carry=0;
for(int i=0;i<a.size()||i<b.size();i++)
{
int temp1=a[i]-'0'-carry,temp2=0;
if(i<b.size()) temp2=b[i]-'0';
carry=0;
if(temp1<temp2)///退位
{
temp1+=10;
carry++;
}
c.push_back(char('0'+temp1-temp2));
}
int i;
reverse(c.begin(),c.end());
for(i=0;i<c.size()-1&&c[i]=='0';i++);///把前面的0删去,但保证至少有一个
c=c.substr(i,c.size()-i);
return c;
}
string multply(string a,string b)
{
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
int c[10005]={0};
string ans;
for(int i=0;i<a.size();i++)///注意下标都是从0开始
{
for(int j=0;j<b.size();j++)
{///i+j为两个数相乘完的那个数所在位置,例如一个数的第二位×另一个数的第二位,所得数在结果的第四位
c[i+j]=c[i+j]+(a[i]-'0')*(b[j]-'0');///算法核心,不进位乘法
}
}
int temp,carry=0;///该位数的和temp,进位carry,与加法类似
for(int i=0;i<a.size()+b.size();i++)
{
temp=c[i]+carry;
c[i]=temp%10;
carry=temp/10;
}
for(int i=0;i<a.size()+b.size();i++) ans.push_back(char('0'+c[i]));
int i;
for(i=ans.size()-1;ans[i]=='0'&&i>=1;i--); ans=ans.substr(0,i+1);
if(carry!=0) ans.push_back(char('0'+carry));
reverse(ans.begin(),ans.end());
return ans;
}
string change(int a)
{
string ans;
while(a)
{
ans.push_back(char(a%10+'0'));
a/=10;
}
reverse(ans.begin(),ans.end());
return ans;
}
string c[205][205];
void C()
{
c[1][1].push_back('1'),c[1][0].push_back('1');
for(int i=2;i<=200;i++)
{
c[i][0].push_back('1'),c[i][i].push_back('1');
for(int j=1;j<=200;j++)
{
c[i][j]=add(c[i-1][j-1],c[i-1][j]);
}
}
}
string pow(string d,int n)///高精度小数乘幂
{
string ans("1");
///先删除0,再删除点否则"100."样例会出错
int i;
for(i=d.size()-1;d[i]=='0'&&i>=0;i--);d.erase(i+1);///删除d后缀0
int index=d.find('.');
if(index!=-1)d.erase(index,1);///删除'.'
index=d.size()-index;///d的小数部分的位数
for(int i=1;i<=n;i++) ans=multply(ans,d);
index=index*n;///ans的小数部分的位数
int len=ans.size();
if(index>len)///小数部分的位数不够不前缀0,说明整数部分是0
{
reverse(ans.begin(),ans.end());
for(int j=0;j<index-len;j++)ans.push_back('0');///补前缀0
ans.push_back('.');///补小数点
reverse(ans.begin(),ans.end());
}
else ans.insert(ans.size()-index,".");///整数部分>0
for(i=ans.size()-1;ans[i]=='0'&&i>=0;i--);ans.erase(i+1);///保险起见删除ans后缀0
return ans;
}
int main()
{
string d,ans("1");
int n;
cin>>d>>n;
int i;
for(i=d.size()-1;d[i]=='0'&&i>=0;i--);d.erase(i+1);///删除d后缀0
int index=d.find('.');
if(index!=-1)d.erase(index,1);///删除.
index=d.size()-index;///d的小数部分的位数
for(int i=1;i<=n;i++) ans=multply(ans,d);
index=index*n;///ans的小数部分的位数
int len=ans.size();
if(index>len)///小数部分的位数不够不前缀0
{
reverse(ans.begin(),ans.end());
for(int j=0;j<index-len;j++)ans.push_back('0');
ans.push_back('.');
reverse(ans.begin(),ans.end());
}
else ans.insert(ans.size()-index,".");
for(i=ans.size()-1;ans[i]=='0'&&i>=0;i--);ans.erase(i+1);///保险起见删除ans后缀0
cout<<ans<<endl;
return 0;
}
上一篇: 快速幂【板子】
推荐阅读