Problem Description
计算国债对于计算机来说是一件很繁重的事情,该问题涉及到的精度很高,现需要你编写一个程序用来计算R的n次方,这里R是一个实数(0.0<R<99.999),而n是一个整数(n<=30)。
Input
第1行是测试数据的组数m,每组测试数据占1行,每行包括一对数R和n。
Output
对应每组测试数据输出一行结果,结果是R的n次的精确值,首尾无意义的零不要输出,如果是整数,不要输出小数点。
Sample Input
2
95.123 12
98.999 10
Sample Output
548815620517731830194541.899025343415715973535967221869852721
90429072743629540498.107596019456651774561044010001
思路:实数相乘和整数相乘差不多,多的一部操作时,对于小数点的处理问题,例:2.5*2.5=6.25,相当于25*25=625在输出答案的时候625后两位的位置加个‘.’。也就是说,重点还是大数相乘,不了解的朋友可以百度:大数乘法。
当时的第一想法是利用3-4个数组大数相乘得出结果。后来实际操作的时候头脑很混乱。后来想到不定数组直接定个int mof,题意说R<99.999,我觉得定个int还是够的,实在不行就long long.
最大的坑是小数点后是不是都是有效数字,如果是12.50的话,我的mof是1250,而我需要的是125,所以这里要判断。
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
int main()//125*125=125*100+125*20+125*5
{
char r[10];
int n;
int T;
scanf("%d",&T);
while(T--){
scanf("%s%d",r,&n);
int a[200]={0};
int len=strlen(r);
int i,j,k;
int mof=0;//modify为原来的底数
for(i=len-1,j=0;i>=0;i--){
if(r[i]=='.'){//计录小数点的位置
k=i;
}
else{
a[j++]=r[i];
}
}
for(i=0;i<k;i++){
mof=mof*10+(r[i]-'0');//把r的整数部分转换为整数型数字
}
if(r[len-1]=='0'){//判断是否有12.50与12.00的情况
for(i=len-2;i>k;i--){
if(r[i]!='0'){
len=i+1;
break;
}
}
if(i==k){
len=k+1;
}
}
if(len-1!=k)//把小数部分转换为整数型数字mof
{
for(i=k+1;i<len;i++){
mof=mof*10+(r[i]-'0');
}
}
int car=0,dig=1,res;//car,dig进位与位数
a[0]=1;
j=0;
for(i=0;i<n;i++){
car=0;
for(j=0;j<dig;j++){//以mof为底数计算
res=mof*a[j]+car;
a[j]=res%10;
car=res/10;
}
while(car){//进位处理
a[dig++]=car%10;
car/=10;
}
}
k=len-k-1;k=k*n;//计算'.'在数中的位置
for(i=dig-1;i>=k; i--){
printf("%d",a[i]);
}
if(len!=0&&k>=1)
printf(".");
for(i=k-1;i>=0;i--){
printf("%d",a[i]);
}
printf("\n");
}
return 0;
}