概要
xorshift128, xorshift*64, xorshift+128を検証する. 32bitを返すバージョンも作成する.検証はDieharder 3.31.1を使用する.
コード
#include <stdio.h> typedef int s32; typedef unsigned int u32; typedef unsigned long long u64; u32 xorshift128() { static u32 x_ = 123459876; static u32 y_ = 362436069; static u32 z_ = 521288629; static u32 w_ = 88675123; u32 t = x_^(x_<<11); x_ = y_; y_ = z_; z_ = w_; w_ = (w_^(w_>>19)) ^ (t^(t>>8)); return w_; } u64 xorshift64star() { static u64 s_ = 0x8a5cd789635d2dffULL; static const u64 M = 2685821657736338717ULL; u64 s = s_; s_ ^= s>>12; s_ ^= s_<<25; s_ ^= s_>>27; return s * M; } u32 xorshift64star32() { static u64 s_ = 0x8a5cd789635d2dffULL; static u64 r_ = 0; static s32 flag_ = 1; static const u64 M=2685821657736338717ULL; if(flag_^=1){ return (u32)(r_>>32); } u64 s = s_; s_ ^= s>>12; s_ ^= s_<<25; s_ ^= s_>>27; r_ = s * M; return (u32)r_; } u64 xorshift128plus() { static u64 s0_ = 0x8a5cd789635d2dffULL; static u64 s1_ = 0x121fd2155c472f96ULL; u64 s1 = s0_; const u64 s0 = s1_; s0_ = s0; s1 ^= s1<<23; s1_ = s1^s0^(s1>>18)^(s0>>5); return s1_+s0; } u32 xorshift128plus32() { static u64 s0_ = 0x8a5cd789635d2dffULL; static u64 s1_ = 0x121fd2155c472f96ULL; static u64 r_ = 0; static s32 flag_ = 1; if(flag_^=1){ return (u32)(r_>>32); } u64 s1 = s0_; const u64 s0 = s1_; s0_ = s0; s1 ^= s1<<23; s1_ = s1^s0^(s1>>18)^(s0>>5); r_ = s1_+s0; return (u32)r_; } int main(int arc, char** argv) { static const u64 size = 14ULL*1024ULL*1024ULL*1024ULL; FILE* file = NULL; file = fopen("xorshift.bin", "wb"); for(u64 i=0; i<size; i+=4){ u32 x = xorshift128(); fwrite(&x, sizeof(x), 1, file); } fclose(file); file = fopen("xorshift64star.bin", "wb"); for(u64 i=0; i<size; i+=8){ u64 x = xorshift64star(); fwrite(&x, sizeof(x), 1, file); } fclose(file); file = fopen("xorshift64star32.bin", "wb"); for(u64 i=0; i<size; i+=4){ u32 x = xorshift64star32(); fwrite(&x, sizeof(x), 1, file); } fclose(file); file = fopen("xorshift128plus.bin", "wb"); for(u64 i=0; i<size; i+=8){ u64 x = xorshift128plus(); fwrite(&x, sizeof(x), 1, file); } fclose(file); file = fopen("xorshift128plus32.bin", "wb"); for(u64 i=0; i<size; i+=4){ u32 x = xorshift128plus32(); fwrite(&x, sizeof(x), 1, file); } fclose(file); return 0; }
結果
PASSEDではない行を抜き出した.xorshift128
$ dieharder -a -g 201 -f xorshift.bin #=============================================================================# # dieharder version 3.31.1 Copyright 2003 Robert G. Brown # #=============================================================================# rng_name | filename |rands/second| file_input_raw| xorshift.bin| 8.44e+06 | #=============================================================================# test_name |ntup| tsamples |psamples| p-value |Assessment #=============================================================================# sts_serial| 12| 100000| 100|0.99913098| WEAK # The file file_input_raw was rewound 2 times rgb_lagged_sum| 9| 1000000| 100|0.99857250| WEAK Preparing to run test 209. ntuple = 0 # The file file_input_raw was rewound 16 times dab_monobit2| 12| 65000000| 1|0.99999170| WEAK
xorshift64*
$ dieharder -a -g 201 -f xorshift64star.bin #=============================================================================# # dieharder version 3.31.1 Copyright 2003 Robert G. Brown # #=============================================================================# rng_name | filename |rands/second| file_input_raw| xorshift64star.bin| 8.52e+06 | #=============================================================================# test_name |ntup| tsamples |psamples| p-value |Assessment #=============================================================================# diehard_oqso| 0| 2097152| 100|0.99886404| WEAK diehard_craps| 0| 200000| 100|0.99772387| WEAK sts_serial| 6| 100000| 100|0.99999972| FAILED sts_serial| 13| 100000| 100|0.99583499| WEAK # The file file_input_raw was rewound 14 times rgb_lagged_sum| 30| 1000000| 100|0.99834128| WEAK
xorshift128+
$ dieharder -a -g 201 -f xorshift128plus.bin #=============================================================================# # dieharder version 3.31.1 Copyright 2003 Robert G. Brown # #=============================================================================# rng_name | filename |rands/second| file_input_raw| xorshift128plus.bin| 8.42e+06 | #=============================================================================# test_name |ntup| tsamples |psamples| p-value |Assessment #=============================================================================# # The file file_input_raw was rewound 1 times rgb_bitdist| 10| 100000| 100|0.99906642| WEAK
Future Work
PCGの実装.References
George Marsaglia, "Xorshift RNGs"Sebastiano Vigna, "An experimental exploration of Marsaglia's xorshift generators, scrambled"
Sebastiano Vigna, "Further scramblings of Marsaglia's xorshift generators"
0 件のコメント:
コメントを投稿