知识点:小数(大数)乘法
小数乘法的思想,就是把小数变成整数,乘完之后再加小数点。所以这道题的核心是:大数乘法。
#include <cstdio>
#include <cstring>
void times(char *a,char *b,char *t) //大数乘法,a和b相乘,结果赋给t
{
int len_a=strlen(a),len_b=strlen(b);
int c[10]={0},d[200]={0},e[200]={0};
for(int i=0;i<len_a;++i)
c[i]=a[len_a-1-i]-'0';
for(int i=0;i<len_b;++i)
d[i]=b[len_b-1-i]-'0';
int k;
for(int i=0;i<len_a;++i)
for(int j=0;j<len_b;++j)
{
k=i+j;
e[k]+=c[i]*d[j];
if(e[k]>9)
{
e[k+1]+=e[k]/10;
e[k]%=10;
}
}
int len_t=e[k+1] ? k+2 : k+1;
for(int i=0;i<len_t;++i)
t[i]=e[len_t-1-i]+'0';
t[len_t]=0;
}
int main()
{
char tmp[10];
int n;
while(scanf("%s%d",tmp,&n)!=EOF)
{
char r[10];
//从这往下,是将tmp去头去尾,将小数化整数,存到r中
int i,j=0,cnt,end; //cnt记录小数位数,end用于去掉小数后面多于的0
//找第一个不为0的位置,该位置只有两种可能:小数点或数字
for(i=0;tmp[i]=='0';++i);
if(tmp[i]=='.')
{
for(end=strlen(tmp)-1;tmp[end]=='0';--end);
cnt=end-i;
for(++i;tmp[i]=='0'&&tmp[i];++i);
for(;i<=end;++i)
r[j++]=tmp[i];
}
else
{
for(;tmp[i]!='.'&&tmp[i];++i)
r[j++]=tmp[i];
if(tmp[i]==0) cnt=0;
else
{
for(end=strlen(tmp)-1;tmp[end]=='0';--end);
cnt=end-i;
for(++i;i<=end;++i)
r[j++]=tmp[i];
}
}
r[j]=0;
char t[200]; //t存放最终结果
strcpy(t,r);
int flag=cnt; //flag记录小数位数
while(--n)
{
times(r,t,t);
flag+=cnt;
}
int len_t=strlen(t);
if(flag==0) puts(t); //flag=0,说明结果是整数
//flag>=len_t,说明需要在小数点后面、t 前面补0
else if(flag>=len_t)
{
putchar('.');
cnt=flag-len_t;
while(cnt--)
putchar('0');
puts(t);
}
else //小数点在 t 中间
{
flag=len_t-1-flag;
for(i=0;t[i];i++)
{
putchar(t[i]);
if(i==flag) putchar('.');
}
putchar('\n');
}
}
return 0;
}