Description
对数值很大、精度很高的数进行高精度计算是一类十分常见的问题。比如,对国债进行计算就是属于这类问题。
现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <= 25。
Input
T输入包括多组 R 和 n。 R 的值占第 1 到第 6 列,n 的值占第 8 和第 9 列。
Output
对于每组输入,要求输出一行,该行包含精确的 R 的 n 次方。输出需要去掉前导的 0 后不要的 0 。如果输出是整数,不要输出小数点。
Sample Input
95.123 12
0.4321 20
5.1234 15
6.7592 9
98.999 10
1.0100 12
Sample Output
548815620517731830194541.899025343415715973535967221869852721
.00000005148554641076956121994511276767154838481760200726351203835429763013462401
43992025569.928573701266488041146654993318703707511666295476720493953024
29448126.764121021618164430206909037173276672
90429072743629540498.107596019456651774561044010001
1.126825030131969720661201
分析:计算高精度幂可转化为高精度数与低精度数(五位数)的乘积。数据需当做整数计算,再加上小数点,幂的小数点位数为底数小数点的位数*N,然后利用数组存储每次的乘积再不断乘以底数直到得到该底数的N次方,根据小数点位数去掉尾部无效的0。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[6];//底数
int N,len,product[150];//乘积及其长度 ,倒序存储
void multi(int a[],int b)
{
int carry=0;//存储进位
for(int i=0;i<len;i++)
{//从低位开始计算,满十进一
int r=a[i]*b+carry;
carry=r/10;
a[i]=r%10;
}
while(carry>0)
{//剩余的进位
a[len++]=carry%10;
carry/=10;
}
}
int main()
{
int dot,num;//小数点位数和数据值
while(cin>>s>>N)
{
dot=num=0;
for(int i=0;i<strlen(s);i++)
{
if(s[i]=='.')
dot=(strlen(s)-i-1)*N;//幂的小数点位数
else
num=num*10+s[i]-'0';
}
if(num==0)
{
cout<<0<<endl;
continue;
}
product[0]=1;len=1;//乘积初始值设为1
for(int i=0;i<N;i++)
multi(product,num);
int i,end=0;//end记录有效数末位
while(product[end]==0&&end<dot)
end++;
if(dot>=len)
{//小数位数大于有效数据长度,小数点后补0
printf(".");
for(i=0;i<dot-len;i++)
printf("0");
for(i=len-1;i>=end;i--)
printf("%d",product[i]);
}
else
{//小数点在中间
for(i=len-1;i>=end;i--)
{
if(i+1==dot)
{//小数部分先输出小数点
printf(".");
}
printf("%d",product[i]);
}
}
cout<<endl;
}
return 0;
}