Bernoulli numbers

Built-in:

say bernoulli(42).as_frac    #=> 1520097643918070802691/1806

Recursive solution (with auto-memoization):

func bernoulli_number(n) is cached {

    n.is_one && return 1/2
    n.is_odd && return   0

    1 - sum(^n, {|k|
        binomial(n,k) * __FUNC__(k) / (n - k + 1)
    })
}

for n in (0..60) {
    var Bn = bernoulli_number(n) || next
    printf("B(%2d) = %44s / %s\n", n, Bn.nude)
}

Using Ramanujan's congruences (pretty fast):

func ramanujan_bernoulli_number(n) is cached {

    return 1/2 if n.is_one
    return 0   if n.is_odd

    ((n%6 == 4 ? -1/2 : 1) * (n+3)/3 - sum(1 .. (n - n%6)/6, {|k|
        binomial(n+3, n - 6*k) * __FUNC__(n - 6*k)
    })) / binomial(n+3, n)
}

Using Euler's product formula for the Riemann zeta function and the Von Staudt–Clausen theorem (very fast):

The Akiyama–Tanigawa algorithm:

Output:

Last updated

Was this helpful?