高精度计算

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;
}

 

 

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值