Continued fraction convergents

func num2cfrac(n, r) {
    gather {
        r.times {
            n = 1/((n - take(n.floor.int)) || break)
        }
    }
}

func convergents(x, n) {
    var cfrac = num2cfrac(x, n)

    var(n1, n2) = (0, 1)
    var(d1, d2) = (1, 0)

    gather {
        for z in (cfrac) {
            (n1, n2) = (n2, n2*z + n1)
            (d1, d2) = (d2, d2*z + d1)
            take(n2/d2)
        }
    }
}

var tests = ["415/93", 415/93, "649/200", 649/200, "sqrt(2)", sqrt(2),
             "sqrt(5)", sqrt(5), "golden ratio", (sqrt(5) + 1) / 2   ]

var terms = 8
say "The continued fraction convergents for the following (maximum #{terms} terms) are:"
tests.each_slice(2, {|s,x|
    printf("%15s = %s\n", s, convergents(x, terms).map { .as_frac }.join(' '))
})

Output:

Last updated

Was this helpful?