题目链接:UVA 748
高精度大数乘方,计算方法类似大数乘法,乘方使用多次循环即可。但结果中的小数点位置需要通过计算得到,具体为原有的小数位数*乘方次数即为结果的小数位数。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
const int N=160;
int tem[6],ans[N],res[N];
int main()
{
string s;
int n,dot;
while(cin>>s>>n)
{
int findex=-1,lindex=-1;
memset(ans,0,sizeof(ans));
memset(res,0,sizeof(res));
memset(tem,0,sizeof(tem));
int pos=s.find(".");
if(pos!=(int)string::npos)
dot=(5-pos)*n; //计算结果中的小数位数
int j=0;
for(int i=5;i>=0;i--) //将乘方运算的底数(不包含小数点)提取出来
if(s[i]!='.')
{
ans[j]=res[j]=tem[j]=s[i]-'0';
j++;
}
while(n>=2) //乘方运算
{
n--;
memset(ans,0,sizeof(ans));
for(int i=0;i<5;i++)
for(int j=0;j<N;j++)
{
if(tem[i]==0)
break;
ans[i+j]+=tem[i]*res[j];
for(int k=i+j;ans[k]>9;k++) //处理进位
{
ans[k+1]+=ans[k]/10;
ans[k]%=10;
}
}
for(int i=0;i<N;i++) //将得到的结果存在res中,下次在res的基础上再乘以底数tem
res[i]=ans[i];
}
/*printf("\nans:");
for(int i=0;i<100;i++)
printf("%d",ans[i]);
printf("\n");*/
for(int i=N-1;i>=dot;i--) //寻找小数点右侧最后一个非零数
if(ans[i]>0)
{
findex=i;
break;
}
for(int i=0;i<dot;i++) //寻找小数点左侧第一个非零数
if(ans[i]>0)
{
lindex=i;
break;
}
//同乘法运算相同,结果低位在左,高位在右,因此逆序输出,但要注意小数点的位置
if(findex!=-1)
while(findex>=dot)
printf("%d",ans[findex--]);
if(lindex!=-1)
{
printf(".");
dot--;
while(dot>=lindex)
printf("%d",ans[dot--]);
}
printf("\n");
}
return 0;
}