欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

高精度运算板子(包括小数的高精度乘方)

程序员文章站 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;
}


相关标签: 板子