The Computer Language
Benchmarks Game

pidigits Swift program

source code

/**
 The Computer Language Benchmarks Game
 http://benchmarksgame.alioth.debian.org/
 contributed by Robert F. Dickerson
 fixed by Isaac Gouy
*/

import CGMP

public final class BigInt {

    fileprivate var i = mpz_t()

    public init(_ value: Int = 0) {
        __gmpz_init(&i)
        __gmpz_set_si(&i, value )
    }

    deinit {
        __gmpz_clear(&i)
    }

    public var intValue: Int {
        let ret = __gmpz_get_si(&self.i)
        return ret
    }

}

extension BigInt: Equatable {}
extension BigInt: Comparable {}

public func * (lhs: BigInt, rhs: BigInt) -> BigInt {
    let ret = BigInt()
    __gmpz_mul(&ret.i, &lhs.i, &rhs.i)
    return ret
}

public func * (lhs: Int, rhs: BigInt) -> BigInt {
    let ret = BigInt()
    let tmp = BigInt(lhs)
    __gmpz_mul(&ret.i, &tmp.i, &rhs.i)
    return ret
}

public func + (lhs: BigInt, rhs: BigInt) -> BigInt {
    let ret = BigInt()
    __gmpz_add(&ret.i, &lhs.i, &rhs.i)
    return ret
}

public func += (lhs: inout BigInt, rhs: BigInt) {
    __gmpz_add(&lhs.i, &lhs.i, &rhs.i)
}

public func += (lhs: inout BigInt, rhs: Int) {
    let tmp = BigInt(rhs)
    __gmpz_add(&lhs.i, &lhs.i, &tmp.i)
}

public func *= (lhs: inout BigInt, rhs: BigInt) {
    __gmpz_mul(&lhs.i, &lhs.i, &rhs.i)
}

public func == (lhs: BigInt, rhs: BigInt) -> Bool {
    return (0 == __gmpz_cmp(&lhs.i, &rhs.i))
}

public func != (lhs: BigInt, rhs: BigInt) -> Bool {
    return !(lhs == rhs)
}

public func / (lhs: BigInt, rhs: BigInt) -> BigInt {
    let ret = BigInt(0)
    __gmpz_fdiv_q(&ret.i,&lhs.i,&rhs.i)
    return ret
}

public func /= (lhs: BigInt, rhs: BigInt) {
    __gmpz_fdiv_q(&lhs.i, &lhs.i, &rhs.i)
}

public func <(lhs: BigInt, rhs: BigInt) -> Bool {
    return (__gmpz_cmp(&lhs.i, &rhs.i) < 0)
}

typealias Matrix = (BigInt, BigInt, BigInt, BigInt)

let unit = (BigInt(1), BigInt(0),
            BigInt(0), BigInt(1))

func * (lhs: Matrix, rhs: Matrix) -> Matrix {
    return ((lhs.0*rhs.0)+(lhs.1*rhs.2),
            (lhs.0*rhs.1)+(lhs.1*rhs.3),
            (lhs.2*rhs.0)+(lhs.3*rhs.2),
            (lhs.2*rhs.1)+(lhs.3*rhs.3))
}

func generate(_ k: Int) -> Matrix {
    return (BigInt(k), BigInt(4)*BigInt(k)+BigInt(2),
            BigInt(0), BigInt(2)*BigInt(k)+BigInt(1))
}

func extr(_ m: Matrix, x: BigInt ) -> BigInt {
    let a = (m.0 * x) + m.1
    let b = (m.2 * x) + m.3
    return a/b
}

func safe(_ z: Matrix, n: BigInt) -> Bool {
    return n == extr(z, x: BigInt(4))
}

func prod(_ z: Matrix, n: BigInt) -> Matrix {
    return (BigInt(10), BigInt(-10)*n,
            BigInt(0), BigInt(1)) * z
}

func next (_ z: Matrix) -> BigInt {
    return extr(z, x: BigInt(3))
}

func computePi(withDigits digits: Int) {

    var z = unit
    var n = 0
    var k = 1
    var j = 0

    var buffer = [Int](repeating: 0, count: 10 )

    while n < digits {

        let y = next( z )

        if safe(z, n: y) {

            buffer[j] = y.intValue
            j += 1

            z = prod( z, n: y)
            n += 1

            if j > 9 {
                printOutput(buffer, n: n)
                j = 0
            }

        } else {

            let x = generate(k)
            k += 1
            z = z * x

        }

    }

    if n%10 != 0 {
        printOutput(buffer, n: n)
    }
}

func printOutput(_ buffer: [Int], n: Int) {
    var output = ""
    var count = 0

    for num in buffer {

        if n%10==0 || count < n%10 {
            output += "\(num)"
        } else {
            output += " "
        }

        count += 1
    }

    output += "\t:\(n)"

    print(output)
}

let n: Int = Int(CommandLine.arguments[1])!
computePi(withDigits: n)
    

notes, command-line, and program output

NOTES:
64-bit Ubuntu quad core
Swift version 4.1 (swift-4.1-RELEASE)
Target: x86_64-unknown-linux-gnu




Fri, 30 Mar 2018 00:38:56 GMT

MAKE:
/opt/src/swift-4.1-RELEASE-ubuntu16.10/usr/bin/swiftc pidigits.swift -Ounchecked -I Include/swift/gmp -o pidigits.swift_run
pidigits.swift:8:8: error: no such module 'CGMP'
import CGMP
       ^
/home/dunham/benchmarksgame/nanobench/makefiles/u64q.programs.Makefile:669: recipe for target 'pidigits.swift_run' failed
make: [pidigits.swift_run] Error 1 (ignored)

0.53s to complete and log all make actions

COMMAND LINE:
./pidigits.swift_run 2000

MAKE ERROR