/* ------------------------------------------------------------------------------ isaac64.c: My random number generator for 64-bit machines. By Bob Jenkins, 1996. Public Domain. ------------------------------------------------------------------------------ */ #ifndef STANDARD #include "isaac_standard.h" #endif #ifndef ISAAC64 #include "isaac64.h" #endif #define ind(mm,x) (*(ub8 *)((ub1 *)(mm) + ((x) & ((RANDSIZ-1)<<3)))) #define rngstep(mix,a,b,mm,m,m2,r,x) \ { \ x = *m; \ a = (mix) + *(m2++); \ *(m++) = y = ind(mm,x) + a + b; \ *(r++) = b = ind(mm,y>>RANDSIZL) + x; \ } void isaac64(rand64ctx *ctx) { register ub8 a,b,x,y,*m,*mm,*m2,*r,*mend; mm=ctx->mm; r=ctx->randrsl; a = ctx->aa; b = ctx->bb + (++ctx->cc); for (m = mm, mend = m2 = m+(RANDSIZ/2); m>5) , a, b, mm, m, m2, r, x); rngstep( a^(a<<12) , a, b, mm, m, m2, r, x); rngstep( a^(a>>33) , a, b, mm, m, m2, r, x); } for (m2 = mm; m2>5) , a, b, mm, m, m2, r, x); rngstep( a^(a<<12) , a, b, mm, m, m2, r, x); rngstep( a^(a>>33) , a, b, mm, m, m2, r, x); } ctx->bb = b; ctx->aa = a; } #define mix(a,b,c,d,e,f,g,h) \ { \ a-=e; f^=h>>9; h+=a; \ b-=f; g^=a<<9; a+=b; \ c-=g; h^=b>>23; b+=c; \ d-=h; a^=c<<15; c+=d; \ e-=a; b^=d>>14; d+=e; \ f-=b; c^=e<<20; e+=f; \ g-=c; d^=f>>17; f+=g; \ h-=d; e^=g<<14; g+=h; \ } void rand64init(rand64ctx *ctx, word flag) { word i; ub8 a,b,c,d,e,f,g,h; ub8 *mm, *randrsl; ctx->aa = ctx->bb = ctx->cc = (ub8)0; mm=ctx->mm; randrsl=ctx->randrsl; a=b=c=d=e=f=g=h=0x9e3779b97f4a7c13LL; /* the golden ratio */ for (i=0; i<4; ++i) /* scramble it */ { mix(a,b,c,d,e,f,g,h); } for (i=0; irandcnt=RANDSIZ; /* prepare to use the first set of results */ } #ifdef NEVER int main() { ub8 i,j; rand64ctx ctx; ctx.aa=ctx.bb=ctx.cc=(ub8)0; for (i=0; i>32),(ub4)ctx.randrsl[j]); if ((j&3)==3) printf("\n"); } } } #endif