小数化分数

中南大学2013年8月31日 月赛

题意:小数化既约分数形式,这道题应该来自编程之美的《浮点数的精确表示》,相当于解题报告。

在这里我就不赘述了。

1.如果没有循环节或者循环节为0

       X=0.a1a2a3...an(0000)

      10^n*X=a1a2a3...an;

那么求最大公约数即可。

2.如果带有非0的循环节
      X=0.a1a2a3...an(b1b2...bm)
     10^n*X=a1a2a3...an.(b1b2...bm);

这里令Y=0.(b1b2...bm),a=a1a2a3...an,b=b1b2...bm

Y*10^m-b=Y;故Y=b/(10^m-1);

那么 X=(a*(10^m-1)+b) / 10^n*(10^m-1);

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define LL long long

LL a,b,basea,baseb;
void split(char str[])
{
    int i=2;
    a=b=0;
    basea=baseb=1;
    while(str[i]&&str[i]!='(')
    {
        a=a*10+(str[i]-'0');
        i++;
        basea*=10;
    }
    if(str[i]=='(')i++;
    while(str[i]&&str[i]!=')')
    {
        b=b*10+(str[i]-'0');
        i++;
        baseb*=10;
    }
}
LL GCD(LL n,LL m)
{
    return  m?GCD(m,n%m):n;
}
int main()
{
    char str[30];
    LL n,m;
    while(~scanf("%s",str))
    {
        split(str);
       /* if(a==0&&b==0)
        {
            printf("0\n");
            continue;
        }
        */
      //  (a*(baseb-1)+b)/basea*(baseb-1);
       if(b==0)//存在循环节为0的情况
        {
              n=a;
              m=basea;
        }
        else
        {
            n=a*(baseb-1)+b;
            m=basea*(baseb-1);
        }
        LL key=GCD(n,m);
       cout<<n/key<<"/"<<m/key<<endl;
    }
    return 0;
}






### C语言中小数分数的实现 为了在C语言中将小数转换为分数,可以通过以下方式实现。此过程涉及读取一个小数值并将其表示为最简形式的分数。 #### 定义函数用于计算最大公约数 (GCD) 首先定义一个辅助函数 `gcd` 来求解两个整数的最大公约数(Greatest Common Divisor),这一步骤对于简最终得到的分数至关重要[^3]: ```c #include <stdio.h> // 计算两数的最大公约数 int gcd(int a, int b) { if (b == 0) return a; else return gcd(b, a % b); } ``` #### 主要逻辑:从小数分数 接下来编写主要功能部分,这里假设输入的是正的小数,并且不考虑负数情况以及大于等于1的情况作为简单例子展示。实际应用时可以根据需求调整范围限制。 ```c void decimalToFraction(double dec, int *numerator, int *denominator) { double tolerance = 1e-6; // 设置精度阈值 // 初始分子分母初值 *denominator = 1; while ((dec - (*numerator)/(*denominator)) > tolerance || ((*numerator)/(*denominator)-dec) > tolerance){ ++(*denominator); *numerator = round(dec * (*denominator)); // 使用 GCD 函数简当前获得的结果 int divisor = gcd(*numerator,*denominator); *numerator /=divisor ; *denominator/=divisor ; } } int main(){ double value = 0.75; // 测试用例中的小数值 int numerator=0 , denominator=0; decimalToFraction(value,&numerator,&denominator); printf("%.2f 的近似分数是:%d/%d\n",value,numerator,denominator); return 0; } ``` 上述代码片段展示了如何把给定的一个双精度浮点数(`double`)转为其对应的分数表达形式。其中采用了逐步增加分母直到找到满足一定误差范围内最佳匹配的方式;同时利用之前提到过的`gcd()`来进行约分简工作以确保输出是最简的真分数形态[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值