分数与小数的相互转换

小数转化为分数

 

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1717

 

题意:把小数转化为分数,循环部分用()表示。


void Work(char str[])  
{  
    int len = strlen(str);  
    LL a = 0;  
    LL b = 0;  
    int cnt1 = 0;  
    int cnt2 = 0;  
    for(int i=2;i<len;i++)  
    {  
        if(str[i] == '(') break;  
        a = a * 10 + str[i] - '0';  
        cnt1++;  
    }  
    bool flag = false;  
    for(int i=2;i<len;i++)  
    {  
        if(str[i] == '(' || str[i] == ')')  
        {  
            flag = true;  
            continue;  
        }  
        b = b * 10 + str[i] - '0';  
        cnt2++;  
    }  
    cnt2 -= cnt1;  
    LL p = b - a;  
    LL q = 0;  
    if(!flag)  
    {  
        p = b;  
        q = 1;  
        cnt2 = 0;  
    }  
    for(int i=0;i<cnt2;i++)  
        q = q * 10 + 9;  
    for(int i=0;i<cnt1;i++)  
        q = q * 10;  
    LL g = gcd(p,q);  
    p /= g;  
    q /= g;  
    cout<<p<<"/"<<q<<endl;  
}  



 

分数转化为小数

 

题目:http://acm.hdu.edu.cn/showproblem.php?pid=2522

 

定理1:有理数a/b (其中0<a<b,(a,b)=1)能表示成纯循环小数的充要条件是(b,10)=1

定理2:有理数a/b, 0<a<b, (a,b)=1,b=(2^α)*(5^β)*b1, (b1,10)=1,b1不等于1,α,β不全为零,则a/b可以表示为纯

     循环小数,其不循环的位数为u = max(α,β)

定理1的证明参见  薛利敏的论文  纯循环小数循环节的规律

定理2的证明:通过把b拆成2部分,(10^u)*b1,当然分子a要相应乘以(2^(u-α))*(5^(u-β))即为a'=a*(2^(u-α))*(5^(u-β)),这样对于a'/b1先化成真分数,大于1的部分就是不循环小数部分,小于1的是纯循环小数部分,得证。

 

void Work(int n)  
{  
    bool flag = 0;  
    int ans[N],f[N];  
    memset(ans,0,sizeof(ans));  
    memset(f,0,sizeof(f));  
    if(n < 0)  
    {  
        n = -n;  
        flag = 1;  
    }  
    int k = 1;  
    f[k] = 1;  
    int cnt = 0;  
    while(k && n != 1)  
    {  
        k *= 10;  
        ans[cnt++] = k / n;  
        k %= n;  
        if(f[k]) break;  
        f[k] = 1;  
    }  
    if(flag) printf("-");  
    if(n == 1) puts("1");  
    else  
    {  
        printf("0.");  
        for(int i=0;i<cnt;i++)  
            printf("%d",ans[i]);  
        puts("");  
    }  
}  


你可能感兴趣的:(分数与小数的相互转换)