POJ-1001 求高精度幂-大数乘法系列

    题目描述:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <= 25。输入数据中每行1-6列为R的值,n的值为8-9列。对于输出答案,需要去除无用的前导0和后续0。整数的话不要输出小数点。

    这是一个高精度乘法的问题,只是比普通的大数乘法多了小数点处理和冗余0处理的问题。

    首先需要把输入数据的小数点去掉,并记录小数点位置(变量为int point),最后处理时,小数点位置在point * n。此时注意对整数需要特殊处理一下。

    对于大数相乘问题,可以手写几遍乘法,观察一下过程,然后用程序模拟。这里给出一种相对另类的乘法过程,即在最高位预留出一位最高位进位位,然后从数字高位向数字低位逐位做乘法并累加,然后再从低位结果向高位结果处理。

    对于小数点和冗余0处理的先后问题,要先处理小数点,把最终结果加上小数点后,再消去冗余0。

    下面是AC代码:

# include<stdio.h>
# include<string.h>
# include<stdlib.h>
int _res[1000];//此处数组若为char型会发生溢出,注意注意
void mul(char a[],char b[])
{
    int i,j,la,lb;
    la=strlen(a);
    lb=strlen(b);
    for (i=0; i<la+lb; i++)
        _res[i]=0;
    for (i=0; i<la; i++)
        for (j=0; j<lb; j++)
            _res[i+j+1]+=(a[i]-'0')*(b[j]-'0');
    for (i=la+lb-1; i>0; i--)
    {
        if (_res[i]>=10)
        {
            _res[i-1]+=_res[i]/10;
            _res[i]%=10;
        }
    }
    i=0;
    while (_res[i]==0)
        i++;
    for (j=0; i<la+lb; i++,j++)
        a[j]=_res[i]+'0';
    a[j]=0;
}
int main()
{
    char res[1000],r[10];
    int n;
    while(~scanf("%s %d",r,&n))
    {
        char m[10]= {0};
        int i,j,point=-1,judge=0;
        for(i=0; i<1000; ++i) res[i]=0;
        for(i=0,j=0; i<6; ++i)
            if(r[i]!='.') m[j++]=r[i];
            else point=strlen(r)-j-1;
        res[0]='1';
        point*=n;
        while(n--)
        {
            mul(res,m);
        }
        if(point>0)
        {
            for(i=0,j=strlen(res)-1; i<=j; ++i,--j) res[i]=res[i]+res[j]-(res[j]=res[i]);//结果逆置后方便添加小数点
            i=strlen(res);
            if(point>=i)
            {
                for(i=strlen(res); i<=point; ++i) res[i]='0';
                res[point]='.';
                res[point+1]=0;
            }
            else
            {
                while(i>=point)
                {
                    res[i]=res[i-1];
                    --i;
                }
                res[point]='.';
            }
            for(i=0,j=strlen(res)-1; i<=j; ++i,--j) res[i]=res[i]+res[j]-(res[j]=res[i]);//再次逆置回来方便去除后续0以及输出
            i=strlen(res)-1;
            while(res[i]=='0') res[i--]=0;
        }
        if(res[strlen(res)-1]=='.')res[strlen(res)-1]=0;
        printf("%s\n",res);
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值