百练 浮点数求高精度幂

转自: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,厉害。



猜你喜欢

转载自blog.csdn.net/huanting74/article/details/80449093