高精度乘法(小数)

来源:互联网 发布:域名含义查询 编辑:程序博客网 时间:2024/05/01 08:25

POJ-1523: 浮点数高精度

题面链接

  • 题意

    输入两个数R( 0.0 < R < 99.999 ) 和 n ( 0 < n <= 25)
    输出R^n(去除前导零和后导零)

  • 样例输入

    95.123 12
    0.4321 20
    5.1234 15
    6.7592 9
    98.999 10
    1.0100 12
    10.00 1

  • 样例输出

    548815620517731830194541.899025343415715973535967221869852721
    .00000005148554641076956121994511276767154838481760200726351203835429763013462401
    43992025569.928573701266488041146654993318703707511666295476720493953024
    29448126.764121021618164430206909037173276672
    90429072743629540498.107596019456651774561044010001
    1.126825030131969720661201
    10

  • 分析

    先将后导零去掉再参与计算

    和整数高精度乘法相似,先找出 小数点的位置(从后往前的第 i 个位置)将小数处理成整数(小数点之后的每一位依次前移一位,此时字符串长度 L-1
    将字符串赋值给数组a 倒序 存入
    和高精度整数乘法相似 s数组赋值给b 循环n次
    在输出的时候注意小数点和去掉 前导零

  • 提示

各个标记数,数组的清空一定不要忽略,对于某些你认为可以清空也可以不清空的并且清空对时间限制没有什么影响的还是清空为好(ps:自己在写的时候因为一个自认为可以不初始化的flag1没初始化,结果改了好久才发现)

  • 代码
#include<stdio.h>#include<string.h>#include<iostream>using namespace std;#define N 1111char s1[N];int i,j,k,l1,l2,l,n,a[N],b[N],s[N],flag1,flag2,flag3,flag4,flag=0,sum;int main(){    while(~scanf("%s%d",s1,&n))    {        l1=strlen(s1);        memset(a,0,sizeof(a));///a*b        memset(b,0,sizeof(b));        memset(s,0,sizeof(s));///a*b=s        b[0]=1;///求a^n  ,先用a*1=s,再a*s=s循环直到结果        flag=0;///用以标记是否已经扫到了小数点        flag1=0;///代表该浮点数有几位小数        flag2=0;        flag3=0;        flag4=0;        l2=1;        sum=0;        for(i=l1-1;i>=0;i--)        {            if(s1[i]-'0'==0)                l1--;///去除后导零(由于一定会有小数点所以倒序判断的等于零的数)            else                break;///直到出现第一个不为零的数停止        }        for(i=0;i<l1-1;i++)        {            if(s1[i]=='.')            {                flag1=l1-i-1;///flag1代表该浮点数有几位小数                //printf("%d\n",flag1);                flag=1;///标记已经遇到小数点了            }            if(flag==1)            {                s1[i]=s1[i+1];                sum+=s1[i]-'0';            }        }        if(sum==0)///如果小数点后的数全为零则不输出小数点        {            l1-=flag1;            flag2=1;///标记不该输出小数点的情况        }        l1--;///去掉了小数点,字符串长度-1        for(i=0;i<l1;i++)            a[l1-i-1]=s1[i]-'0';///将字符串里的数倒序存放        for(k=0;k<n;k++)///n次循环相乘        {            for(i=0;i<l1;i++)            {                for(j=0;j<l2;j++)                {                    s[i+j]+=a[i]*b[j];                    if(s[i+j]>=10)///进位                    {                        s[i+j+1]+=s[i+j]/10;                        s[i+j]%=10;                    }                }            }            l=l1+l2;            memset(b,0,sizeof(b));///清空b数组            for(i=0;i<l;i++)                b[i]=s[i];///把s数组里的值赋值给b数组            if(k==n-1)///如果循环到最后一次            {                for(i=l-1;i>=0;i--)                {                    if(i==n*flag1-1&&flag2==0)                    {                        printf(".");                        flag3=1;                    }                    if(s[i]!=0)                    {                        flag4=1;                    }                    if(flag4==1||flag3==1)///去前导零                        printf("%d",s[i]);                }                printf("\n");            }            l2=l;            memset(s,0,sizeof(s));        }    }    return 0;}
0 0