V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
crella
V2EX  ›  问与答

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

  •  
  •   crella · 2019-08-09 16:28:17 +08:00 · 1418 次点击
    这是一个创建于 1693 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如某道题给出某个数值 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   ·   我们的愿景   ·   实用小工具   ·   3016 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 14:55 · PVG 22:55 · LAX 07:55 · JFK 10:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.