Description
对数值很大、精度很高的数进行高精度计算是一类十分常见的问题。比如,对国债进行计算就是属于这类问题。
现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <= 25。
现在要你解决的问题是:对一个实数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 。如果输出是整数,不要输出小数点。
一道高精度数据计算题。当数值位数超过计算机所能表示范围后,一般会用数组或者链表的形式来表示数据,如果是数组,可以每位数存在一项中,如果是链表,可以4位数的存。这里是幂运算,也就是R*R*R...*R,模拟乘法其实就是把平时笔算乘法的逻辑用计算机语言实现一下。
首先读取输入数据:
char temp[6]={0};
int lp[5]={0};//数字部分,不含小数点
unsigned int n=0;//幂
unsigned int ib=0;//整数位数
while(1)
{
cin>>temp;
cin>>n;
int i=0;
while(temp[i]!='.')
{
ib++;
i++;
}
for(int c=0;c<ib;c++)
{
lp[4-c]=temp[c]-'0';
}//将整数部分填入数组
for(int c=0;c<5-ib;c++)
{
lp[c]=temp[5-c]-'0';
}//将小数部分填入数组,这样lp保存了去除小数点的剩下五位数
print_res(lp,ib,n);//计算过程,见下
memset(temp,0,sizeof(char)*6);//清除,准备下次计算
memset(lp,0,sizeof(int)*5);
ib=0;
}
然后是计算函数:
int print_res(int* lp,int ib,int n)//数字部分,整数位数,指数
{
memcpy(temp,lp,5*sizeof(int));//拷贝被乘数
for(int c=1;c<n;c++)
{
for(int i=0;i<5;i++)
{
for(int j=0;j<100;j++)//相当于被乘数逐位与乘数当前位相乘
{
int res=temp[j]*lp[i];//相乘结果
ipart[i+j]=res+ipart[i+j];//与之前的计算结果相加
ipart[i+j+1]=(ipart[i+j]-ipart[i+j]%10)/10+ipart[i+j+1];//十位数进位
ipart[i+j]=ipart[i+j]%10;//取个位数
}
}
memcpy(temp,ipart,105*sizeof(int));//拷贝被乘数
memset(ipart,0,105*sizeof(int));//
}
bool is_print=false;
for(int i=99;i>=(5-ib)*n;i--)//最高位
{
if(temp[i]!=0)
is_print=true;
if(is_print)
{
cout<<temp[i];
}
}
int ws=0;//计算小数部分最后几个多余0的个数,这部分不需要输出
for(int i=0;i<100;i++)
{
if(temp[i]!=0)break;
ws++;
}
if(4*n-1!=ws+1)//如果多余的0等于小数位数,则不输出.
{
cout<<".";
}
for(int i=4*n-1;i>=ws;i--)//输出小数部分
{
cout<<temp[i];
}
cout<<endl;
memset(temp,0,105*sizeof(int));
memset(ipart,0,105*sizeof(int));
return 1;
}