有一个把 34 位小数智能转换为分数的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
crella
V2EX    问与答

有一个把 34 位小数智能转换为分数的问题

  •  
  •   crella 2019-08-09 16:28:17 +08:00 1938 次点击
    这是一个创建于 2262 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如某道题给出某个数值 a 为 0.5833,我想猜出来它是一个怎样的分数。

    比较正经的方法是假设 a=0.583..3(无限循环)=0.58+0.01[x]0.3..3(无限循环)=29/50+1/100[x]1/3=7/12。

    如果懒一点,假设转换出来的分数不存在大于 11 的倍数,则 2[x]3[x]5[x]7[x]11=2310,m=2310[x]0.5833=1347.42 。

    当 m 取 1347,1347=3[x]449[x]1,1347 和 2310 的公约数为 3,化简后分数为 449/770。

    当 m 取 1348,则化简后分数为 674/1155.

    当 m 取 1347.4,并且让 2310 乘 10,则化简后分数,6737/11550.

    现在的问题是,如果是用正经的方法,当对于从文本读取来的一堆有限位小数时,怎样才能想象出它的无限循环部分呢?或许可以通过限制分母的大小来要求重新走流程?

    假设 a 是 0.58330330..=0.58(330,无限循环),那么 a 就变成 29/50+3/100[x](100/999+1/99)=4856/8325。

    如果是用懒人的方法,请指教如何修改可以得到完美的"7/12".
    谢谢各位。

    #这语法自动把*号转 markdown 了。。
    9 条回复    2019-08-09 19:48:11 +08:00
    crella
        1
    crella  
    OP
       2019-08-09 16:37:15 +08:00
    如果假设 a 的循环方式是 0.5(833,无限循环),则 a=1/2+1/10*100/999*(8+3/10+3/100)=2914/4995,这个看起来也不是很好..
    snakeyou
        2
    snakeyou  
       2019-08-09 17:07:30 +08:00
    设阈值,
    (0.5833*x)离整数的距离小于阈值,
    否则 0.5833 的分数只能是 5833/10000 了。
    ipwx
        3
    ipwx  
       2019-08-09 17:11:13 +08:00   1
    geelaw
        4
    geelaw  
       2019-08-09 17:36:18 +08:00 via iPhone
    连分数渐近+1

    一个连分数的渐近项是所有分母不超过该渐近项的分母的分数中最佳的近似,且恰好就是所有这样的近似。

    计算连分数也非常容易反复求倒数并取小数部分,
    dazkarieh
        5
    dazkarieh  
       2019-08-09 17:50:00 +08:00
    我知道有个叫 Math Tools 的 alfred workflow 可以实现小数转分数的功能
    https://github.com/Emrys365/alfred_workflows

    frac 0.5833333
    显示结果
    ≈7/12
    crella
        6
    crella  
    OP
       2019-08-09 18:16:36 +08:00
    @snakeyou
    @ipwx
    @geelaw
    @dazkarieh
    我说得有点不清楚。比如有个小数是 0.11688,按照那个 rosettacode 的 c#示例,求出来是 475/4064,然而按我设想要的结果是 9/77。

    事实上 9/77=0.11688312,475/4064=0.11687992.

    如果我是想要在满足近似范围里面让分子和分母加起来最小,那应该怎么办呢?所以我才想到用 2*3*5*7*{质数列}作为分母的方法。

    额,我一开始并不是假设 0.583 就等于 0.58(3..3,无限循环),而是找一个分数,满足近似范围里面,而分数比较简单,也可以说成分子和分母之和最小吧。
    crella
        7
    crella  
    OP
       2019-08-09 18:44:04 +08:00
    应该可以描述成这样吧:

    设 a 为有限长的小数,集合 M{(x,y)}满足|x/y-a|<定值 e,求使 x+y 取到最小值的(x,y)的算法。
    geelaw
        8
    geelaw  
       2019-08-09 19:47:45 +08:00 via iPhone
    @crella #7 假设 a 是真分数,那么显然最佳的 x、y 满足 y=O(1/e)

    在此基础上,可以看出 x+y=(x/y-a)y+(1+a)y=(1+a)y+O(1),因此寻找 x+y 最小等价于 y 接近最小。

    具体的估算只是苦力,就留作楼主习题。

    一旦知道这件事之后,问题就回到选择以后买个合适的连分数渐近项。
    geelaw
        9
    geelaw  
       2019-08-09 19:48:11 +08:00 via iPhone
    @geelaw *选择以后买个 -> 选择一个
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1649 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 16:19 PVG 00:19 LAX 09:19 JFK 12:19
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86