File Coverage

isaac64.h
Criterion Covered Total %
statement 32 42 76.1
branch 11 16 68.7
condition n/a
subroutine n/a
pod n/a
total 43 58 74.1


line stmt bran cond sub pod time code
1              
2              
3             /*
4              
5             ISAAC64 Random number generator based on code by Bob Jenkins on the public domain
6              
7             See http://burtleburtle.net/bob/rand/isaacafa.html
8              
9             */
10              
11             #define RANDSIZL (8)
12             #define RANDSIZ (1<
13              
14             struct isaac64_state {
15             uint64_t randrsl[RANDSIZ], randcnt;
16             uint64_t mm[RANDSIZ];
17             uint64_t aa, bb, cc;
18             };
19              
20             typedef struct isaac64_state isaac64_state_t;
21              
22             #define ind(mm,x) (*(uint64_t *)((unsigned char *)(mm) + ((x) & ((RANDSIZ-1)<<3))))
23             #define rngstep(mix,a,b,mm,m,m2,r,x) \
24             { \
25             x = *m; \
26             a = (mix) + *(m2++); \
27             *(m++) = y = ind(mm,x) + a + b; \
28             *(r++) = b = ind(mm,y>>RANDSIZL) + x; \
29             }
30              
31 9           void isaac64(isaac64_state_t *is) {
32             uint64_t a,b,x,y,*m,*m2,*r,*mend;
33 9           m=is->mm; r=is->randrsl;
34 9           a = is->aa; b = is->bb + (++is->cc);
35 297 100         for (m = is->mm, mend = m2 = m+(RANDSIZ/2); m
36             {
37 288           rngstep(~(a^(a<<21)), a, b, is->mm, m, m2, r, x);
38 288           rngstep( a^(a>>5) , a, b, is->mm, m, m2, r, x);
39 288           rngstep( a^(a<<12) , a, b, is->mm, m, m2, r, x);
40 288           rngstep( a^(a>>33) , a, b, is->mm, m, m2, r, x);
41             }
42 297 100         for (m2 = is->mm; m2
43             {
44 288           rngstep(~(a^(a<<21)), a, b, is->mm, m, m2, r, x);
45 288           rngstep( a^(a>>5) , a, b, is->mm, m, m2, r, x);
46 288           rngstep( a^(a<<12) , a, b, is->mm, m, m2, r, x);
47 288           rngstep( a^(a>>33) , a, b, is->mm, m, m2, r, x);
48             }
49 9           is->bb = b; is->aa = a;
50 9           }
51              
52             #define mix(a,b,c,d,e,f,g,h) \
53             { \
54             a-=e; f^=h>>9; h+=a; \
55             b-=f; g^=a<<9; a+=b; \
56             c-=g; h^=b>>23; b+=c; \
57             d-=h; a^=c<<15; c+=d; \
58             e-=a; b^=d>>14; d+=e; \
59             f-=b; c^=e<<20; e+=f; \
60             g-=c; d^=f>>17; f+=g; \
61             h-=d; e^=g<<14; g+=h; \
62             }
63              
64 9           void randinit(isaac64_state_t *is, int flag) {
65             int i;
66             uint64_t a,b,c,d,e,f,g,h;
67 9           is->aa=is->bb=is->cc=(uint64_t)0;
68             #ifdef _MSC_VER
69             a=b=c=d=e=f=g=h=0x9e3779b97f4a7c13; /* the golden ratio */
70             #else
71 9           a=b=c=d=e=f=g=h=0x9e3779b97f4a7c13LLU; /* the golden ratio */
72             #endif
73              
74 45 100         for (i=0; i<4; ++i) /* scramble it */
75             {
76 36           mix(a,b,c,d,e,f,g,h);
77             }
78              
79 297 100         for (i=0; i
80             {
81 288 50         if (flag) /* use all the information in the seed */
82             {
83 0           a+=is->randrsl[i ]; b+=is->randrsl[i+1]; c+=is->randrsl[i+2]; d+=is->randrsl[i+3];
84 0           e+=is->randrsl[i+4]; f+=is->randrsl[i+5]; g+=is->randrsl[i+6]; h+=is->randrsl[i+7];
85             }
86 288           mix(a,b,c,d,e,f,g,h);
87 288           is->mm[i ]=a; is->mm[i+1]=b; is->mm[i+2]=c; is->mm[i+3]=d;
88 288           is->mm[i+4]=e; is->mm[i+5]=f; is->mm[i+6]=g; is->mm[i+7]=h;
89             }
90            
91 9 50         if (flag)
92             { /* do a second pass to make all of the seed affect all of mm */
93 0 0         for (i=0; i
94             {
95 0           a+=is->mm[i ]; b+=is->mm[i+1]; c+=is->mm[i+2]; d+=is->mm[i+3];
96 0           e+=is->mm[i+4]; f+=is->mm[i+5]; g+=is->mm[i+6]; h+=is->mm[i+7];
97 0           mix(a,b,c,d,e,f,g,h);
98 0           is->mm[i ]=a; is->mm[i+1]=b; is->mm[i+2]=c; is->mm[i+3]=d;
99 0           is->mm[i+4]=e; is->mm[i+5]=f; is->mm[i+6]=g; is->mm[i+7]=h;
100             }
101             }
102              
103 9           isaac64(is); /* fill in the first set of results */
104 9           is->randcnt=RANDSIZ; /* prepare to use the first set of results */
105 9           }
106              
107             static uint64_t
108 300           rand64(isaac64_state_t *is) {
109 300 50         if( ! is->randcnt--) {
110 0           isaac64(is);
111 0           is->randcnt = RANDSIZ-1;
112             }
113 300           return is->randrsl[is->randcnt];
114             }