Task: Almkvist-Giullera formula for pi




Go: package main

import (
    "fmt"
    "math/big"
    "strings"
)

func factorial(n int64) *big.Int {
    var z big.Int
    return z.MulRange(1, n)
}

var one = big.NewInt(1)
var three = big.NewInt(3)
var six = big.NewInt(6)
var ten = big.NewInt(10)
var seventy = big.NewInt(70)

func almkvistGiullera(n int64, print bool) *big.Rat {
    t1 := big.NewInt(32)
    t1.Mul(factorial(6*n), t1)
    t2 := big.NewInt(532*n*n + 126*n + 9)
    t3 := new(big.Int)
    t3.Exp(factorial(n), six, nil)
    t3.Mul(t3, three)
    ip := new(big.Int)
    ip.Mul(t1, t2)
    ip.Quo(ip, t3)
    pw := 6*n + 3
    t1.SetInt64(pw)
    tm := new(big.Rat).SetFrac(ip, t1.Exp(ten, t1, nil))
    if print {
        fmt.Printf("%d  %44d  %3d  %-35s\n", n, ip, -pw, tm.FloatString(33))
    }
    return tm
}

func main() {
    fmt.Println("N                               Integer Portion  Pow  Nth Term (33 dp)")
    fmt.Println(strings.Repeat("-", 89))
    for n := int64(0); n < 10; n++ {
        almkvistGiullera(n, true)
    }

    sum := new(big.Rat)
    prev := new(big.Rat)
    pow70 := new(big.Int).Exp(ten, seventy, nil)
    prec := new(big.Rat).SetFrac(one, pow70)
    n := int64(0)
    for {
        term := almkvistGiullera(n, false)
        sum.Add(sum, term)
        z := new(big.Rat).Sub(sum, prev)
        z.Abs(z)
        if z.Cmp(prec) < 0 {
            break
        }
        prev.Set(sum)
        n++
    }
    sum.Inv(sum)
    pi := new(big.Float).SetPrec(256).SetRat(sum)
    pi.Sqrt(pi)
    fmt.Println("\nPi to 70 decimal places is:")
    fmt.Println(pi.Text('f', 70))
}





VB: Imports System, BI = System.Numerics.BigInteger, System.Console

Module Module1

    Function isqrt(ByVal x As BI) As BI
        Dim t As BI, q As BI = 1, r As BI = 0
        While q <= x : q <<= 2 : End While
        While q > 1 : q >>= 2 : t = x - r - q : r >>= 1
            If t >= 0 Then x = t : r += q
        End While : Return r
    End Function

    Function dump(ByVal digs As Integer, ByVal Optional show As Boolean = False) As String
        digs += 1
        Dim z As Integer, gb As Integer = 1, dg As Integer = digs + gb
        Dim te As BI, t1 As BI = 1, t2 As BI = 9, t3 As BI = 1, su As BI = 0, t As BI = BI.Pow(10, If(dg <= 60, 0, dg - 60)), d As BI = -1, fn As BI = 1
        For n As BI = 0 To dg - 1
            If n > 0 Then t3 = t3 * BI.Pow(n, 6)
            te = t1 * t2 / t3 : z = dg - 1 - CInt(n) * 6
            If z > 0 Then te = te * BI.Pow(10, z) Else te = te / BI.Pow(10, -z)
            If show AndAlso n < 10 Then WriteLine("{0,2} {1,62}", n, te * 32 / 3 / t)
            su += te : If te < 10 Then
                digs -= 1
                If show Then WriteLine(vbLf & "{0} iterations required for {1} digits " & _
                    "after the decimal point." & vbLf, n, digs)
                Exit For
            End If
            For j As BI = n * 6 + 1 To n * 6 + 6
                t1 = t1 * j : Next
            d += 2 : t2 += 126 + 532 * d
        Next
        Dim s As String = String.Format("{0}", isqrt(BI.Pow(10, dg * 2 + 3) _
            / su / 32 * 3 * BI.Pow(CType(10, BI), dg + 5)))
        Return s(0) & "." & s.Substring(1, digs)
    End Function

    Sub Main(ByVal args As String())
        WriteLine(dump(70, true))
    End Sub

End Module