Random으로 수를 생성해낼때 생성해내고자 하는 범위의 수 안에서 고르게 수를 생성해내는건 쉬운일이 아니다.
C언어에서 random 함수를 제공하기는 하지만, 해당 함수를 수만번 돌려보면 생성되는 수의 분포가 어느 한쪽에 치우치는 경향이 강한데, 아래에 소개하는 소스는 생성되는 수가 고르게 분포되어 있다.
프로그램내에 Random 알고리즘을 적용하고자 할때 매우 유용하게 사용할 수 있을것 같다.
/* ***************************************************************************** */ /* Copyright: Francois Panneton and Pierre L'Ecuyer, University of Montreal */ /* Makoto Matsumoto, Hiroshima University */ /* Notice: This code can be used freely for personal, academic, */ /* or non-commercial purposes. For commercial purposes, */ /* please contact P. L'Ecuyer at: lecuyer@iro.UMontreal.ca */ /* ***************************************************************************** */ #define W 32 #define R 16 #define P 0 #define M1 13 #define M2 9 #define M3 5 #define MAT0POS(t,v) (v^(v>>t)) #define MAT0NEG(t,v) (v^(v<<(-(t)))) #define MAT3NEG(t,v) (v<<(-(t))) #define MAT4NEG(t,b,v) (v ^ ((v<<(-(t))) & b)) #define V0 STATE[state_i ] #define VM1 STATE[(state_i+M1) & 0x0000000fU] #define VM2 STATE[(state_i+M2) & 0x0000000fU] #define VM3 STATE[(state_i+M3) & 0x0000000fU] #define VRm1 STATE[(state_i+15) & 0x0000000fU] #define VRm2 STATE[(state_i+14) & 0x0000000fU] #define newV0 STATE[(state_i+15) & 0x0000000fU] #define newV1 STATE[state_i ] #define newVRm1 STATE[(state_i+14) & 0x0000000fU] #define FACT 2.32830643653869628906e-10 static unsigned int state_i = 0; static unsigned int STATE[R]; static unsigned int z0, z1, z2; void InitWELLRNG512a (unsigned int *init){ int j; state_i = 0; for (j = 0; j < R; j++) STATE[j] = init[j]; } double WELLRNG512a (void){ z0 = VRm1; z1 = MAT0NEG (-16,V0) ^ MAT0NEG (-15, VM1); z2 = MAT0POS (11, VM2) ; newV1 = z1 ^ z2; newV0 = MAT0NEG (-2,z0) ^ MAT0NEG(-18,z1) ^ MAT3NEG(-28,z2) ^ MAT4NEG(-5,0xda442d24U,newV1) ; state_i = (state_i + 15) & 0x0000000fU; return ((double) STATE[state_i]) * FACT; }
소스출처 : http://www.iro.umontreal.ca/~panneton/well/WELL512a.c