首页 > 代码库 > 【编程之美】2.6 精确表达浮点数

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

题目: 给一个有限小数 或者 无限循环小数, 用分母最小的方式用分数精确的表达这个数字。 括号中表示循环部分,如:

0.3  , 0.3(3), 0.3(0)

 

思路:我一看,傻眼了,想了两下不想想了,就在网上找循环小数转分数,结果居然是小学奥赛题!我郁闷的很啊.....

拿 1.2(34)来举例子吧

1.2(34) * 10 = 12.34343434...

1.2(34) * 1000 = 1234.3434...

1.2(34) * 1000  - 1.2(34) * 10 = 1234 - 12

990 * 1.2(34) = 1222

1.2(34) = 1222 / 990

 

然后再约分,分子分母同时除以他们的最大公约数就好了。

代码输入是用字符串输入的,需要判断是否有循环节和循环节是否为0

#include <stdio.h>#include <string.h>typedef struct  Fraction{    int numerator;    int denominator;}Fraction;//返回num * 10^powint Tens(int num, int pow){    for(int i = pow; i != 0; i--)    {        num *= 10;    }    return num;}//辗转相除求最大公约数int mod(int num1, int num2){    int a, b;    a = (num1 > num2) ? num1 : num2;    b = (num1 < num2) ? num1 : num2;    int r = a % b;    if(r == 0)        return b;    else    {        a = b;        b = r;        return mod(a, b);    }}Fraction getFractionExperssion(char * in){    int intefer = 0; //整数部分    int WithoutLoop = 0; //不循环部分    int WithLoop = 0; //循环部分    int powWithoutLoop = 0; //不循环部分到第几位小数    int powOfLoop = 0; //循环部分到第几位小数        int numerator = 0; //分子    int denominator = 0; //分母    Fraction ans;        int tmp = 0;    int tmpPowWithoutLoop = 0;    int tmpPowOfLoop = 0;    char * tmpin = in;    bool bHasLoop = false;    while(*tmpin != \0)    {        if(*tmpin >= 0 && *tmpin <= 9)        {            tmp = tmp * 10 + ((*tmpin) - 0);            tmpPowWithoutLoop++;            tmpPowOfLoop++;        }        else if(*tmpin == .)        {            tmpPowWithoutLoop = 0;        }        else if(*tmpin == ()        {            powWithoutLoop = tmpPowWithoutLoop;            WithoutLoop = tmp;            tmpPowOfLoop = 0;            tmp = 0;            bHasLoop = true;        }        else if(*tmpin == ))        {            powOfLoop = tmpPowOfLoop;            WithLoop = tmp;            tmp = 0;        }        else        {            printf("input error!!");        }        tmpin++;    }    //处理没有()的情况    if(!bHasLoop)    {        WithoutLoop = tmp;        powWithoutLoop = tmpPowWithoutLoop;    }    if(WithLoop == 0) //本身不是循环小数    {        //得到分子分母        numerator = WithoutLoop;        denominator = Tens(1, powWithoutLoop);        //求最大公约数        int gcd = mod(numerator, denominator);        //使答案的分子分母最小        ans.denominator = denominator / gcd;        ans.numerator = numerator / gcd;        printf("%s = %d / %d\n", in, ans.numerator, ans.denominator);        return ans;    }    else //是循环小数    {        numerator = Tens(WithoutLoop, powOfLoop) + WithLoop - WithoutLoop;        denominator = Tens(1, powOfLoop + powWithoutLoop) - Tens(1, powWithoutLoop);        int gcd = mod(numerator, denominator);                ans.denominator = denominator / gcd;        ans.numerator = numerator / gcd;        printf("%s = %d / %d\n", in, ans.numerator, ans.denominator);        return ans;    }}int main(){    char * in1 = "3.3(3)";    char * in2 = "2.3(12)";    char * in3 = "0.300(0)";    getFractionExperssion(in1);    getFractionExperssion(in2);    getFractionExperssion(in3);    return 0;}

 

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