转自:https://blog.csdn.net/ordinarycrazy/article/details/77799090
总时间限制:
1000ms 内存限制: 65536kB-
描述
-
有一个实数 R ( 0.0 < R < 99.999 ) ,要求写程序精确计算 R 的 n 次方。n 是整数并且 0 < n <= 25。
输入
-
T输入包括多组 R 和 n。 R 的值占第 1 到 第 6 列, n 的值占第 8 和第 9 列。
输出
- 对于每组输入,要求输出一行,该行包含精确的 R 的 n 次方。输出需要去掉前导的 0 后后面不不要的 0 。如果输出是整数,不要输出小数点。 样例输入
-
95.123 12 0.4321 20 5.1234 15 6.7592 9 98.999 10 1.0100 12
样例输出
-
548815620517731830194541.899025343415715973535967221869852721 .00000005148554641076956121994511276767154838481760200726351203835429763013462401 43992025569.928573701266488041146654993318703707511666295476720493953024 29448126.764121021618164430206909037173276672 90429072743629540498.107596019456651774561044010001 1.126825030131969720661201
#include <stdio.h>
#include <string.h>
/********************************************
基本的思路就是我们先找到小数点最终的位置,然后按照大整数乘法来解决这个问题
*********************************************/
void multiply(int* n1,int* n2)//n1乘n2,结果放在n2里
{
int i,j,tmp[250];
memset(tmp,0,sizeof(tmp));
for(i = 0;i < 5;i++)
for(j = 0;j < 246;j++)
tmp[i+j] += n1[i] * n2[j]; //模拟手动乘法
for(i = 0;i < 248;i++)
{
tmp[i+1] += tmp[i]/10; //整理进位
tmp[i] %= 10;
}
memcpy(n2,tmp,sizeof(tmp));
}
int main()
{
char r[7];
int n,i,j,point,res[250],num[5];
while(scanf("%s%d",r,&n)!=EOF) //使用string来接收。
{
point = 0;
while(r[point] != '.') point++;//point现在知道小数点前面有几个数字
for(i = point;i < 5;i++)
r[i] = r[i+1];
point = 5 - point;
point *= n;//最终结果小数点后的位数
for(i = 4;i >= 0;i--)
num[4 - i] = r[i] - '0';//将数的低位依次放置。
memset(res,0,sizeof(res));
res[0]=1; //初始化为1,相当于是第一次一次幂。
for(i = 0;i < n;i++)
multiply(num,res);
int len = 250;
while(res[--len] == 0);
for(i = len;i >= point;i--)
printf("%d",res[i]); //倒序输出整数部分。
for(i = 0;i < point;i++)//检查小数部分是否为零 ,这里也就把那些像是1.0100的输入,的最后末尾的0给过滤掉了。
if(res[i] != 0)
break;
if(i < point)//如果小数位不全为0,那么则输出,也是倒序输出。
{
printf(".");
for(j = point-1;j >= i;j--) //这里只输出到i,i之前的都为0了
printf("%d",res[j]);
}
printf("\n");
}
return 0;
}
PS:头一次做大数乘法的题目,明白了。但是不太明白为什么 最后小数点后的位数=原始小数点后的位数*幂次。
最后的检查不输出多余的0,厉害。