Calculate the Bernoulli numbers in go

This is an example Go program for calculating the Bernoulli numbers. The formula used here is taken from "Complex Analysis" by Serge Lang, second edition, page 47. The outputs agree with the Wikipedia article on Bernoulli numbers up to the values tested.

The math/big package in Go seems to require exceptionally verbose code like this, there seems to be no simple way to multiply rationals by integers or divide one rational by another, and according to the documentation, all the functions have the odd feature of both overwriting their arguments and also returning the value, but if I have done this the wrong way then please let me know. My email address is at the bottom of the page.

package main

import (
        "fmt"
        "math/big"
)

// Factorials
var f []*big.Int
var max int64 = 16
var one = big.NewInt(int64(1))

func makeF() {
        f = make([]*big.Int, max)
        f[0] = big.NewInt(1)
        if false {
                fmt.Printf("%d! = %s\n", 0, f[0])
        }
        for i := int64(1); i < max; i++ {
                f[i] = new(big.Int)
                f[i].Mul(f[i-1], big.NewInt(i))
                if false {
                        fmt.Printf("%d! = %s\n", i, f[i])
                }
        }
}

func bernoulli(b []*big.Rat, n int64) {
        b[n-1] = big.NewRat(0, int64(1))
        for i := int64(0); i < n-1; i++ {
                c := new(big.Rat).Set(b[i])
                d := new(big.Int).Set(f[i])
                d.Mul(d, f[n-i])
                if false {
                        fmt.Printf("%d!%d! = %s\n", n-i, i, d)
                }
                dinv := new(big.Rat).SetInt(d)
                c.Mul(c, dinv.Inv(dinv))
                c.Neg(c)
                b[n-1].Add(b[n-1], c)
        }
        b[n-1].Mul(b[n-1], new(big.Rat).SetInt(f[n-1]))
        fmt.Printf("B_%d: %s\n", n-1, b[n-1])
}

func main() {
        makeF()
        b := make([]*big.Rat, max)
        b[0] = big.NewRat(int64(1), int64(1))
        for n := int64(2); n < max; n++ {
                bernoulli(b, n)
        }
}

(download)

The output of the example looks like this:

B_1: -1/2
B_2: 1/6
B_3: 0/1
B_4: -1/30
B_5: 0/1
B_6: 1/42
B_7: 0/1
B_8: -1/30
B_9: 0/1
B_10: 5/66
B_11: 0/1
B_12: -691/2730
B_13: 0/1
B_14: 7/6


Copyright © Ben Bullock 2009-2024. All rights reserved. For comments, questions, and corrections, please email Ben Bullock (benkasminbullock@gmail.com). / Privacy / Disclaimer