现在的位置: 首页 > 综合 > 正文

编程之美 2.6 精确表达浮点数

2018年01月19日 ⁄ 综合 ⁄ 共 1179字 ⁄ 字号 评论关闭

2.6精确表达浮点数

问题描述:

使用分数形式来表示小数,有限小数和无限循环小数都可以转化为分数。
例如: 0.9 = 9 / 10 ,0.33333(3) = 1 / 3 。

问题分析:

(1) 若是有限小数,则可以使用以下方法: 0.a1a2a3a4a5..an=a1a2a3a4a5a6an/10^n
(2) 下面主要考虑无限循环小数:
设 X=0.a1a2a3a4a5...an(b1b2b3b4...bm)

10^n*X=a1a2a3a4a5...an.b1b2b3b4...bm(b1b2b3b4...bm)


Y=0.b1b2b3b4... bm(b1b2b3b4...bm)
10^m*Y=b1b2b3b4...bm.(b1b2b3b4...bm)
10^m*Y-Y=b1b2b3b4...bm
Y=b1b2b3b4...bm/(10^m-1)
        
X =((a1a2a3a4...an)*(10^m-1)+b1b2b3b4...bm)/(10^n)*(10^m-1)
         
(3)化简到最后,分子分母可能会出现不是最简的形式, A/B ,
则需要调用(A / gcd(A ,B)) / (B / gcd(A , B)) ,即已经化简完毕。

#include<iostream> 
#include<stdio.h> 
#include<cstring>  
using namespace std;  
  
int gys(int m,int n)//n大 m小   
{  
    int t;//n是底 大些   
    while(m>0)  
    {  
        t=n%m;  
        n=m;  
        m=t;  
    }  
    return n;  
}  
int main()  
{  
    int n,z1,z2,z,p,q,x,y,len,t,i,temp1,temp;  
    char a[14];  
    scanf("%d",&n);  
    while(n--)  
    {  
        scanf("%s",a);  
        len=strlen(a);  
        t=0;//有无括号   
        p=0;x=0;//前面an的   
        q=0;y=0;//bn的   
        for(i=2;i<len;i++)  
        {  
            if(!t&&a[i]!='(')   
            {  
                p++;x=x*10;x+=a[i]-'0';  
            }  
            if(t&&a[i]!=')')   
            {  
                q++;y=y*10;y+=a[i]-'0';  
            }  
            if(a[i]=='(')  
                t=1;      
        }  
        if(!q)//有限循环   
        {  
            temp=1;//10^p 程序的10^p 是异或。   
            for(i=0;i<p;i++)  
                temp*=10;  
                  
            z=gys(x,temp);  
            printf("%d/%d\n",x/z,temp/z);      
        }  
        else  
        {  
            temp=1;//10^p  
            for(i=0;i<p;i++)  
                temp*=10;  
                  
            temp1=1;//10^q  
            for(i=0;i<q;i++)  
                temp1*=10;  
                                  
            z1=x*(temp1-1)+y;  
            z2=(temp1-1)*(temp);  
            z=gys(z1,z2);  
            printf("%d/%d\n",z1/z,z2/z);      
        }      
    }      
    return 0;  
}   

抱歉!评论已关闭.