LoginSignup
1
2

More than 5 years have passed since last update.

Xorshift のGoでの実装 (32ビット版だけ)

Posted at

本日は

Go の練習がてらXorshiftを実装してみます.

実装例(struct を使う場合)

package main

import "fmt"

type xorshift32 struct {
    seed uint32
}

func (r *xorshift32) rand() uint32 {
    y := r.seed
    y = y ^ (y << 13)
    y = y ^ (y >> 17)
    y = y ^ (y << 5)
    r.seed = y
    return y
}

func uniform(generator xorshift32) func() float32 {
    inner := func() float32 {
        return float32(generator.rand()) / float32(^uint32(0))
    }
    return inner
}

func calcPi() {
    xor32 := xorshift32{seed: 2463534242}
    u01 := uniform(xor32)
    N := 100000000
    counter := 0
    for i := 0; i < N; i++ {
        x := u01()
        y := u01()
        if x*x+y*y < 1.0 {
            counter += 1
        }
    }
    fmt.Println(4 * float64(counter) / float64(N))
}

func test1() {
    xor32 := xorshift32{seed: 2463534242}
    for i := 0; i < 10; i++ {
        fmt.Println(xor32.rand())
    }
}

func main() {
    test1()
    calcPi()
}

xor32.rand() を複数呼び出す際に seed,y の値を記録しておく必要があるので struct を使いました.ポインターレシーバーのの良い練習になりました.

実装例(クロージャを用いた場合)

Xorshift の Python 実装
にならって書いた場合です.

package main

import "fmt"

func randXorshit32(seed uint32) func() uint32 {
    var y uint32 = seed
    inner := func() uint32 {
        y = y ^ (y << 13)
        y = y ^ (y >> 17)
        y = y ^ (y << 5)
        return y
    }
    return inner
}

func uniform(generator func() uint32) func() float32 {
    inner := func() float32 {
        return float32(generator()) / float32(^uint32(0))
    }
    return inner
}

func calcPi() {
    xor32 := randXorshit32(2463534242)
    u01 := uniform(xor32)
    N := 100000000
    counter := 0
    for i := 0; i < N; i++ {
        x := u01()
        y := u01()
        if x*x+y*y < 1.0 {
            counter += 1
        }
    }
    fmt.Println(4 * float64(counter) / float64(N))
}

func test1() {
    xor32 := randXorshit32(2463534242)
    for i := 0; i < 10; i++ {
        fmt.Println(xor32())
    }

}

func main() {
    test1()
    calcPi()
}

書いていて思ったこと

Pythonに慣れてしまった人間から見るとGoがデフォルト引数をサポートしていないというのがとても不便に感じてしまします.

そういうもんなんだろうな・・・.

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2