为了账号安全,请及时绑定邮箱和手机立即绑定

如何将浮点数转换为人类可读的分数?

如何将浮点数转换为人类可读的分数?

如何将浮点数转换为人类可读的分数?假设我们有0.33,我们需要输出“1/3”。如果我们有“0.4”,我们需要输出“2/5”。我们的想法是让人们可读,让用户理解“y部分中的x部分”,作为理解数据的更好方式。我知道百分比是一个很好的替代品,但我想知道是否有一个简单的方法来做到这一点?
查看完整描述

3 回答

?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

我发现David Eppstein 发现给定实数 C代码的理性近似正是你所要求的。它基于连续分数理论,非常快速且相当紧凑。

我已经为特定的分子和分母限制使用了这个版本。

/*** find rational approximation to given real number** David Eppstein / UC Irvine / 8 Aug 1993**** With corrections from Arno Formella, May 2008**** usage: a.out r d**   r is real number to approx**   d is the maximum denominator allowed**** based on the theory of continued fractions** if x = a1 + 1/(a2 + 1/(a3 + 1/(a4 + ...)))** then best approximation is found by truncating this series** (with some adjustments in the last term).**** Note the fraction can be recovered as the first column of the matrix**  ( a1 1 ) ( a2 1 ) ( a3 1 ) ...**  ( 1  0 ) ( 1  0 ) ( 1  0 )** Instead of keeping the sequence of continued fraction terms,** we just keep the last partial product of these matrices.*/#include <stdio.h>main(ac, av)int ac;char ** av;{
    double atof();
    int atoi();
    void exit();
    long m[2][2];
    double x, startx;
    long maxden;
    long ai;
    /* read command line arguments */
    if (ac != 3) {
        fprintf(stderr, "usage: %s r d\n",av[0]);  // AF: argument missing
        exit(1);
    }
    startx = x = atof(av[1]);
    maxden = atoi(av[2]);
    /* initialize matrix */
    m[0][0] = m[1][1] = 1;
    m[0][1] = m[1][0] = 0;
    /* loop finding terms until denom gets too big */
    while (m[1][0] *  ( ai = (long)x ) + m[1][1] <= maxden) {
        long t;
        t = m[0][0] * ai + m[0][1];
        m[0][1] = m[0][0];
        m[0][0] = t;
        t = m[1][0] * ai + m[1][1];
        m[1][1] = m[1][0];
        m[1][0] = t;
        if(x==(double)ai) break;     // AF: division by zero
        x = 1/(x - (double) ai);
        if(x>(double)0x7FFFFFFF) break;  // AF: representation failure
    } 
    /* now remaining x is between 0 and 1/ai */
    /* approx as either 0 or 1/m where m is max that will fit in maxden */
    /* first try zero */
    printf("%ld/%ld, error = %e\n", m[0][0], m[1][0],
           startx - ((double) m[0][0] / (double) m[1][0]));
    /* now try other possibility */
    ai = (maxden - m[1][1]) / m[1][0];
    m[0][0] = m[0][0] * ai + m[0][1];
    m[1][0] = m[1][0] * ai + m[1][1];
    printf("%ld/%ld, error = %e\n", m[0][0], m[1][0],
           startx - ((double) m[0][0] / (double) m[1][0]));}


查看完整回答
反对 回复 2019-07-26
?
守着星空守着你

TA贡献1799条经验 获得超8个赞

从Python 2.6开始就有fractions模块。

(引用文档。)

>>> from fractions import Fraction>>> Fraction('3.1415926535897932').limit_denominator(1000)Fraction(355, 113)>>> from math import pi, cos>>> Fraction.from_float(cos(pi/3))Fraction(4503599627370497, 9007199254740992)>>> Fraction.from_float(cos(pi/3)).limit_denominator()Fraction(1, 2)


查看完整回答
反对 回复 2019-07-26
?
温温酱

TA贡献1752条经验 获得超4个赞

如果输出是为了给人类读者一个结果顺序的快速印象,那么返回“113/211”之类的东西是没有意义的,所以输出应该限制为使用一位数字(也许是1 / 10和9/10)。如果是这样,您可以观察到只有27 种不同的分数。

由于用于生成输出的基础数学将永远不会改变,因此解决方案可能是简单地对二进制搜索树进行硬编码,以便该函数最多执行log(27)〜= 4 3/4比较。这是经过测试的C版代码

char *userTextForDouble(double d, char *rval){
    if (d == 0.0)
        return "0";
    // TODO: negative numbers:if (d < 0.0)...
    if (d >= 1.0)
        sprintf(rval, "%.0f ", floor(d));
    d = d-floor(d); // now only the fractional part is left
    if (d == 0.0)
        return rval;
    if( d < 0.47 )
    {
        if( d < 0.25 )
        {
            if( d < 0.16 )
            {
                if( d < 0.12 ) // Note: fixed from .13
                {
                    if( d < 0.11 )
                        strcat(rval, "1/10"); // .1
                    else
                        strcat(rval, "1/9"); // .1111....
                }
                else // d >= .12
                {
                    if( d < 0.14 )
                        strcat(rval, "1/8"); // .125
                    else
                        strcat(rval, "1/7"); // .1428...
                }
            }
            else // d >= .16
            {
                if( d < 0.19 )
                {
                    strcat(rval, "1/6"); // .1666...
                }
                else // d > .19
                {
                    if( d < 0.22 )
                        strcat(rval, "1/5"); // .2
                    else
                        strcat(rval, "2/9"); // .2222...
                }
            }
        }
        else // d >= .25
        {
            if( d < 0.37 ) // Note: fixed from .38
            {
                if( d < 0.28 ) // Note: fixed from .29
                {
                    strcat(rval, "1/4"); // .25
                }
                else // d >=.28
                {
                    if( d < 0.31 )
                        strcat(rval, "2/7"); // .2857...
                    else
                        strcat(rval, "1/3"); // .3333...
                }
            }
            else // d >= .37
            {
                if( d < 0.42 ) // Note: fixed from .43
                {
                    if( d < 0.40 )
                        strcat(rval, "3/8"); // .375
                    else
                        strcat(rval, "2/5"); // .4
                }
                else // d >= .42
                {
                    if( d < 0.44 )
                        strcat(rval, "3/7"); // .4285...
                    else
                        strcat(rval, "4/9"); // .4444...
                }
            }
        }
    }
    else
    {
        if( d < 0.71 )
        {
            if( d < 0.60 )
            {
                if( d < 0.55 ) // Note: fixed from .56
                {
                    strcat(rval, "1/2"); // .5
                }
                else // d >= .55
                {
                    if( d < 0.57 )
                        strcat(rval, "5/9"); // .5555...
                    else
                        strcat(rval, "4/7"); // .5714
                }
            }
            else // d >= .6
            {
                if( d < 0.62 ) // Note: Fixed from .63
                {
                    strcat(rval, "3/5"); // .6
                }
                else // d >= .62
                {
                    if( d < 0.66 )
                        strcat(rval, "5/8"); // .625
                    else
                        strcat(rval, "2/3"); // .6666...
                }
            }
        }
        else
        {
            if( d < 0.80 )
            {
                if( d < 0.74 )
                {
                    strcat(rval, "5/7"); // .7142...
                }
                else // d >= .74
                {
                    if(d < 0.77 ) // Note: fixed from .78
                        strcat(rval, "3/4"); // .75
                    else
                        strcat(rval, "7/9"); // .7777...
                }
            }
            else // d >= .8
            {
                if( d < 0.85 ) // Note: fixed from .86
                {
                    if( d < 0.83 )
                        strcat(rval, "4/5"); // .8
                    else
                        strcat(rval, "5/6"); // .8333...
                }
                else // d >= .85
                {
                    if( d < 0.87 ) // Note: fixed from .88
                    {
                        strcat(rval, "6/7"); // .8571
                    }
                    else // d >= .87
                    {
                        if( d < 0.88 ) // Note: fixed from .89
                        {
                            strcat(rval, "7/8"); // .875
                        }
                        else // d >= .88
                        {
                            if( d < 0.90 )
                                strcat(rval, "8/9"); // .8888...
                            else
                                strcat(rval, "9/10"); // .9
                        }
                    }
                }
            }
        }
    }
    return rval;}


查看完整回答
反对 回复 2019-07-26
  • 3 回答
  • 0 关注
  • 830 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信