本日は
C,Python,Go にひきつづいて Nim による Xorshiftを実装してみます.
Nim by Example: For Loops & Iterators
のClosure Iteratorsの項目を参考にしました.
実装例
# Reference:https://nim-by-example.github.io/for_iterators/
import math
proc xorshift32(seed = uint32(2463534242)): iterator(): uint32 =
return iterator(): uint32 =
var y = seed
while true:
y = y xor (y shl 13)
y = y xor (y shr 17)
y = y xor (y shl 5)
yield y
proc uniform(rand=xorshift32(), b=0.0,e=1.0): iterator():float64=
const maxUint32 = math.pow(2.0,32.0)-1
return iterator():float64=
while true:
var value=b+float64(rand())/maxUint32/(e-b)
yield value
when isMainModule:
var N=100_000_000
var counter=0
var uniform01=uniform()
var x,y :float64
for i in 1..N:
x=uniform01()
y=uniform01()
if x*x+y*y<1.0:
counter+=1
echo "Pi=", 4.0*float64(counter)/float64(N)
シフト演算子が>ふたつで実現するのではなく専用の二項演算が定義されることを調べるのに時間がかかりました.じつはTutorialのChapter1にこっそりと記されています:
The and or xor not operators are also defined for integers, and provide bitwise operations. Left bit shifting is done with the shl, right shifting with the shr operator. Bit shifting operators always treat their arguments as unsigned. For arithmetic bit shifts ordinary multiplication or division can be used.
NimはPythonのように関数(proc)の引数にデフォルト引数を定義できるのでうれしいです.といってもNim独特のクセがありますが.Nimは書けるようになると楽しく書けますが,かけるまでの壁が高めな気がします・・・.