1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

XorShiftの実装 軽量版

Last updated at Posted at 2018-10-13

以前作った記事が余計な処理含みすぎて複雑になりすぎたので(若干言語のラインナップは変わってますが)シェイプアップして書き直しました。
対応言語はJavaScript、VB、HSP、CommonLisp、C#、Python3、D言語、C++、Lua、Ruby、Tclです。
どの言語でも実装を合わせれば乱数の再現が可能です。
シードは変えた記録も載せていますが、時間をシードとして使い、偏り防止のためにこちらに倣って最初に40回ほど空転させています。

w=default
3701687786
458299110
2500872618
3633119408
516391518
2377269574
2599949379
717229868
137866584
395339113

w=time
2976958265
1697336156
4079413984
3258662528
4114964721
3389760686
247342821
359323276
3421929016
1548721468

実装

JavaScript(Node.js)
"use strict";

function* XorShift(w=88675123,x=123456789,y=362436069,z=521288629){
	var t;
	for(;;){
		t=x^(x<<11);
		x=y;y=z;z=w;
		yield w=((w^(w>>>19))^(t^(t>>>8)))>>>0;
	}
}

console.log("w=default");
const r=XorShift();
for(var i=0;i<10;i++){
	console.log(r.next().value);
}

console.log("\nw=time");
const rt=XorShift(0|Date.now());
for(var i=0;i<40;i++) rt.next();
for(var i=0;i<10;i++){
	console.log(rt.next().value);
}
VisualBasic(VB.Net)
Option Strict On
Imports System.Collections.Generic

Module Program
	Iterator Function XorShift(Optional w As UInteger=88675123,Optional x As UInteger=123456789,Optional y As UInteger=362436069,Optional z As UInteger=521288629) As IEnumerator(Of UInteger)
		Dim t As UInteger
		Do
			t=x Xor (x<<11)
			x=y:y=z:z=w
			w=(w Xor (w>>19)) Xor (t Xor (t>>8))
			Yield w
		Loop
	End Function

	Sub Main()
		Console.WriteLine("w=default")
		Dim r=XorShift()
		For i=1 To 10
			r.MoveNext()
			Console.WriteLine(r.Current)
		Next

		Console.WriteLine($"{vbLf}w=time")
		Dim rt=XorShift(CUInt(DateTime.UtcNow.Ticks And &H7FFFFFFF))
		For i=1 To 40: rt.MoveNext(): Next
		For i=1 To 10
			rt.MoveNext()
			Console.WriteLine(rt.Current)
		Next
	End Sub
End Module
HotSoupProcessor(HSP3)
# runtime "hsp3cl"
# cmpopt varinit 1

# module @XorShift co,w,x,y,z
	#define global XorShift(%1,%2=88675123,%3=123456789,%4=362436069,%5=521288629) \
		dimtype %1,5:newmod %1,@XorShift,%2,%3,%4,%5
	#modinit int _w,int _x,int _y,int _z
		w=_w:x=_x:y=_y:z=_z
		newlab co,1:return
		*xsLoop
			t=x^(x<<11)
			x=y:y=z:z=w
			w=(w^(w>>19&$1FFF))^(t^(t>>8&$FFFFFF))
			newlab co,1:return
		goto*xsLoop
	return
	#modfunc xsMoveNext
		gosub co: return double(strf("%u",w))
	#modcfunc xsNext
		gosub co: return double(strf("%u",w))
# global

mes "w=default"
XorShift r
repeat 10
	mes strf("%.0f",xsNext(r))
loop

mes "\nw=time"
XorShift rt,1000*(60*(60*(24*gettime(3)+gettime(4))+gettime(5))+gettime(6))+gettime(7)
repeat 40: xsMoveNext rt: loop
repeat 10
	mes strf("%.0f",xsNext(rt))
loop
CommonLisp
(defun XorShift(&key (w 88675123) (x 123456789) (y 362436069) (z 521288629))
	(let (tt)
		(lambda()
			(setf tt (logxor x (logand (ash x 11) #xFFFFFFFF)))
			(setf x y)(setf y z)(setf z w)
			(setf w (logxor (logxor w (ash w -19)) (logxor tt (ash tt -8))))
		)
	)
)

(format t "w=default~%")
(let ((r (XorShift)))
	(dotimes(i 10)
		(format t "~d~%" (funcall r))
	)
)

(format t "~%w=time~%")
(let ((rt (XorShift :w (get-universal-time))))
	(dotimes(i 40) (funcall rt))
	(dotimes(i 10)
		(format t "~d~%" (funcall rt))
	)
)
(quit)
C#
using System;
using System.Collections.Generic;

class Program{
	static IEnumerator<uint> XorShift(uint w=88675123,uint x=123456789,uint y=362436069,uint z=521288629){
		uint t;
		for(;;){
			t=x^(x<<11);
			x=y;y=z;z=w;
			yield return w=(w^(w>>19))^(t^(t>>8));
		}
	}

	static void Main(){
		Console.WriteLine("w=default");
		var r=XorShift();
		for(int i=0;i<10;i++){
			r.MoveNext();
			Console.WriteLine(r.Current);
		}

		Console.WriteLine("\nw=time");
		var rt=XorShift((uint)DateTime.UtcNow.Ticks);
		for(int i=0;i<40;i++) rt.MoveNext();
		for(int i=0;i<10;i++){
			rt.MoveNext();
			Console.WriteLine(rt.Current);
		}
	}
}
Python3
from time import time

def XorShift(x=123456789,y=362436069,z=521288629,w=88675123):
	while True:
		t=x^(x<<11&0xFFFFFFFF)
		x,y,z=y,z,w
		w=(w^(w>>19))^(t^(t>>8))
		yield w

print("w=default")
r=XorShift()
for i in range(0,10):
	print(next(r))

print("\nw=time")
rt=XorShift(int(time()))
for i in range(0,40): next(rt)
for i in range(0,10):
	print(next(rt))
Dlang(D言語)
import std.stdio;
import std.concurrency;
import std.datetime;

Generator!uint XorShift(uint w=88675123,uint x=123456789,uint y=362436069,uint z=521288629){
	return new Generator!uint((){
		yield(w);
		uint t;
		for(;;){
			t=x^(x<<11);
			x=y;y=z;z=w;
			yield(w=(w^(w>>19))^(t^(t>>8)));
		}
	});
}

void main(){
	writeln("w=default");
	auto r=XorShift();
	for(int i=0;i<10;i++){
		r.popFront();
		writeln(r.front);
	}

	writeln("\nw=time");
	auto rt=XorShift(cast(uint)Clock.currTime().stdTime);
	for(int i=0;i<40;i++) rt.popFront();
	for(int i=0;i<10;i++){
		rt.popFront();
		writeln(rt.front);
	}
}
C++
# include <iostream>
# include <stdint.h>
# include <time.h>

class XorShift{
private:
	uint32_t w,x,y,z,t;
public:
	XorShift(uint32_t w=88675123,uint32_t x=123456789,uint32_t y=362436069,uint32_t z=521288629){
		this->w=w;this->x=x;this->y=y;this->z=z;
	}
	uint32_t next(){
		t=x^(x<<11);
		x=y;y=z;z=w;
		return w=(w^(w>>19))^(t^(t>>8));
	}
};

int main(){
	using namespace std;
	cout<<"w=default"<<endl;
	XorShift r;
	for(auto i=0;i<10;i++){
		cout<<r.next()<<endl;
	}

	cout<<"\nw=time"<<endl;
	XorShift rt(time(nullptr));
	for(auto i=0;i<40;i++) rt.next();
	for(auto i=0;i<10;i++){
		cout<<rt.next()<<endl;
	}
	return 0;
}
Lua
function XorShift(w,x,y,z)
	w=w or 88675123:x=x or 123456789:y=y or 362436069:z=z or 521288629
    return coroutine.create(function()
		while true do
			t=x~(x<<11&0xFFFFFFFF)
			x,y,z=y,z,w
			w=(w~(w>>19))~(t~(t>>8))
			coroutine.yield(w)
        end
    end)
end

print("w=default")
local r=XorShift()
for i=1,10 do
    print(({coroutine.resume(r)})[2])
end

print("\nw=time")
local rt=XorShift(os.time())
for i=1,40 do coroutine.resume(rt) end
for i=1,10 do
    print(({coroutine.resume(rt)})[2])
end
Ruby
def XorShift(x=123456789,y=362436069,z=521288629,w=88675123)
	Fiber.new do
		while true do
			t=x^(x<<11&0xFFFFFFFF)
			x,y,z=y,z,w
			w=(w^(w>>19))^(t^(t>>8))
			Fiber.yield(w)
		end
	end
end

puts "w=default"
r=XorShift()
(1..10).each do
	puts r.resume
end

puts "\nw=time"
rt=XorShift(Time.now.tv_sec)
(1..40).each do rt.resume end
(1..10).each do
	puts rt.resume
end
Tcl
proc XorShift {{w 88675123} {x 123456789} {y 362436069} {z 521288629}} {
    yield [info coroutine]
    while true {
		set t [expr $x^($x<<11&0xFFFFFFFF)]
		set x $y;set y $z;set z $w
		yield [set w [expr ($w^($w>>19))^($t^($t>>8))]]
    }
}

puts "w=default"
coroutine r XorShift
for {set i 0} {$i<10} {incr i} {
	puts [r]
}

puts "\nw=time"
coroutine rt XorShift [expr [clock clicks -milliseconds]&0xFFFFFFFF]
for {set i 0} {$i<40} {incr i} rt
for {set i 0} {$i<10} {incr i} {
	puts [rt]
}
1
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?