高精度的乘法应用

/*
对于一个实数R(0<R<99.999),要求写程序精确计算R的n次方,其中n是整数。并且0<n<=25
输入:输入包括多组R和n,R的值占第1列到第六列,n的值占第8和第9列。
输出:对于每组输入,要求输出一行,该行包含精确的R的n次方,输出需要去掉前导的0后不要的0,如果输出的是整数,则不要输出小数点



分析:输入比较规范,前六位是第一个数A,后面是该数的N次方,大整数的乘法可以模拟笔算乘法来做
    第一步:处理输入的数A的小数点,先把小数点去掉,把原来的数存储到一个整形的数组中,记录小数点的位置,然后在开一个整数数组存储中间结果
    第二步:设数组1和数组2一开始存储A,数组3是中间数组,每次由数组3来保存数组1和数组2的相乘的结果,然后把数组3赋值到数组1中,得出的结果后就是计算小数点的位置了。
    第三部:这个有原来的位置就可以确定现在小数点的位置了,不过要注意的是运算过程中数组是反向的,确定小数点的位置后还要去掉前导0和后导0,这可以通过确定其起始位和终止位来输出数组1中的保存结果。
注意:输入的时候永远都是小的数在最高位

                                    1  2  3
                                       4  6
                                -------------------
                                    6  12 18
                                 4  8  12


*/
#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
char str[10];
int n,dot;
int res[99999],a[99999],b[99999];
int la,lb;
void  mul()
{
    int i,j;
    memset(res,0,sizeof(res));
    for(i=1;i<=la;i++)
    {
        for(j=1;j<=lb;j++)
        {
            res[i+j-1]=res[i+j-1]+a[i]*b[j];                      //由于乘法的特点,与下面的数进行对齐,对齐的坐标的取法就是这样的.
            if(res[i+j-1]>9)
            {
                res[i+j]=res[i+j]+res[i+j-1]/10;                            //进位,由于i,j的取值是从1开始取的,所以可以直接超前进位。这里满足的是数位越高越在前面
                res[i+j-1]=res[i+j-1]%10;
            }
        }
    }
    if(res[la+lb-1]>9)
    {
        res[la+lb]=res[la+lb]+res[la+lb-1]/10;
        res[la+lb-1]=res[la+lb-1]%10;
    }
    la=la+lb;
    for(i=1;i<=la;i++)
    {
        a[i]=res[i];
        //cout<<a[i];
    }
    //cout<<endl;



}
int main()
{
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    int up,down,i,j;
    while(scanf("%s %d",str,&n)!=EOF)
    {
        dot=-1;
        for(i=5,j=1;i>=0;i--)
        {
            if(str[i]!='.')
            {
                a[j]=b[j]=str[i]-'0';
                j++;
            }
//倒叙存储小数点后面的数字
            else
                dot=i;                      //dot记录小数点所在的位置,并且dot的值就是前面整数的位数
        }

        //for(i=1;i<=5;i++)
        //    cout<<a[i];
        if(dot==-1)
            la=lb=6;
        else
            la=lb=5;                        //含有小数点的时候数字位数就是5
        for(i=1;i<n;i++)                   //n的值就是指数幂的值
            mul();
        if(dot==-1)
        {
            for(i=la;i>=1;i--)
                cout<<a[i];
            cout<<endl;
        }
        else
        {
            dot=5-dot;                                  //因为在前面,我们使用dot判断小数点的位置,数字在没有倒叙的时候是个位数在最前面,所以,使用5-dot就可以得到小数的位数
            dot=dot*n;
            for(i=1;i<=la;i++)
            {
                if(a[i]!=0)
                {
                    down=i;
                    break;
                }
            }
            for(j=la;j>=1;j--)
            {
                if(a[j]!=0)
                {
                    up=j;
                    break;
                }
            }
            i=up;                               //i为数的最高位,j为数非零的最低位,如果最低位的j>dot,证明这个数是一个整数,所以,dot就点在dot+1的位置便可
            if(up<dot)                          //如果i<dot,则证明这个数最后小于1,所以这个时候的小数点就要点在dot
                i=dot;
            j=down;
            if(j>dot)
                j=dot+1;
            for(;i>=j;i--)
            {
                if(i==dot)
                {
                    cout<<'.';
                }
                cout<<a[i];
            }
            cout<<endl;
        }
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值