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

#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];
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;
}



struct bign{
    int d[maxn], len;

	void clean() { while(len > 1 && !d[len-1]) len--; }

    bign() 			{ memset(d, 0, sizeof(d)); len = 1; }
    bign(int num) 	{ *this = num; }
	bign(char* num) { *this = num; }
    bign operator = (const char* num){
        memset(d, 0, sizeof(d)); len = strlen(num);
        for(int i = 0; i < len; i++) d[i] = num[len-1-i] - '0';
        clean();
		return *this;
    }
    bign operator = (int num){
        char s[20]; sprintf(s, "%d", num);
        *this = s;
		return *this;
    }

    bign operator + (const bign& b){
        bign c = *this; int i;
        for (i = 0; i < b.len; i++){
        	c.d[i] += b.d[i];
        	if (c.d[i] > 9) c.d[i]%=10, c.d[i+1]++;
		}
		while (c.d[i] > 9) c.d[i++]%=10, c.d[i]++;
		c.len = max(len, b.len);
		if (c.d[i] && c.len <= i) c.len = i+1;
        return c;
    }
    bign operator - (const bign& b){
        bign c = *this; int i;
        for (i = 0; i < b.len; i++){
        	c.d[i] -= b.d[i];
        	if (c.d[i] < 0) c.d[i]+=10, c.d[i+1]--;
		}
		while (c.d[i] < 0) c.d[i++]+=10, c.d[i]--;
		c.clean();
		return c;
    }
    bign operator * (const bign& b)const{
        int i, j; bign c; c.len = len + b.len;
        for(j = 0; j < b.len; j++) for(i = 0; i < len; i++)
			c.d[i+j] += d[i] * b.d[j];
        for(i = 0; i < c.len-1; i++)
            c.d[i+1] += c.d[i]/10, c.d[i] %= 10;
        c.clean();
		return c;
    }
    bign operator / (const bign& b){
    	int i, j;
		bign c = *this, a = 0;
    	for (i = len - 1; i >= 0; i--)
    	{
    		a = a*10 + d[i];
    		for (j = 0; j < 10; j++) if (a < b*(j+1)) break;
    		c.d[i] = j;
    		a = a - b*j;
    	}
    	c.clean();
    	return c;
    }
    bign operator % (const bign& b){
    	int i, j;
		bign a = 0;
    	for (i = len - 1; i >= 0; i--)
    	{
    		a = a*10 + d[i];
    		for (j = 0; j < 10; j++) if (a < b*(j+1)) break;
    		a = a - b*j;
    	}
    	return a;
    }
	bign operator += (const bign& b){
        *this = *this + b;
        return *this;
    }

    bool operator <(const bign& b) const{
        if(len != b.len) return len < b.len;
        for(int i = len-1; i >= 0; i--)
            if(d[i] != b.d[i]) return d[i] < b.d[i];
        return false;
    }
    bool operator >(const bign& b) const{return b < *this;}
    bool operator<=(const bign& b) const{return !(b < *this);}
    bool operator>=(const bign& b) const{return !(*this < b);}
    bool operator!=(const bign& b) const{return b < *this || *this < b;}
    bool operator==(const bign& b) const{return !(b < *this) && !(b > *this);}

    string str() const{
        char s[maxn]={};
        for(int i = 0; i < len; i++) s[len-1-i] = d[i]+'0';
        return s;
    }
};

istream& operator >> (istream& in, bign& x)
{
    string s;
    in >> s;
    x = s.c_str();
    return in;
}

ostream& operator << (ostream& out, const bign& x)
{
    out << x.str();
    return out;
}
发布了95 篇原创文章 · 获赞 7 · 访问量 8456

猜你喜欢

转载自blog.csdn.net/Spidy_harker/article/details/100565735