Merge pull request #50 from lemonsqueeze/can_countercap
[pachi.git] / random.c
blobb719151e644a16ddb600e8c747f31703ff8ffec3
1 #include <stdio.h>
3 #include "random.h"
6 /* Simple Park-Miller for floating point; LCG as used in glibc and other places */
8 #ifndef NO_THREAD_LOCAL
10 static __thread unsigned long pmseed = 29264;
12 void
13 fast_srandom(unsigned long seed_)
15 pmseed = seed_;
18 unsigned long
19 fast_getseed(void)
21 return pmseed;
24 uint16_t
25 fast_random(unsigned int max)
27 pmseed = ((pmseed * 1103515245) + 12345) & 0x7fffffff;
28 return ((pmseed & 0xffff) * max) >> 16;
31 float
32 fast_frandom(void)
34 /* Construct (1,2) IEEE floating_t from our random integer */
35 /* http://rgba.org/articles/sfrand/sfrand.htm */
36 union { unsigned long ul; floating_t f; } p;
37 p.ul = (((pmseed *= 16807) & 0x007fffff) - 1) | 0x3f800000;
38 return p.f - 1.0f;
41 #else
43 /* Thread local storage not supported through __thread,
44 * use pthread_getspecific() instead. */
46 #include <pthread.h>
48 static pthread_key_t seed_key;
50 static void __attribute__((constructor))
51 random_init(void)
53 pthread_key_create(&seed_key, NULL);
54 fast_srandom(29264UL);
57 void
58 fast_srandom(unsigned long seed_)
60 pthread_setspecific(seed_key, (void *)seed_);
63 unsigned long
64 fast_getseed(void)
66 return (unsigned long)pthread_getspecific(seed_key);
69 uint16_t
70 fast_random(unsigned int max)
72 unsigned long pmseed = (unsigned long)pthread_getspecific(seed_key);
73 pmseed = ((pmseed * 1103515245) + 12345) & 0x7fffffff;
74 pthread_setspecific(seed_key, (void *)pmseed);
75 return ((pmseed & 0xffff) * max) >> 16;
78 float
79 fast_frandom(void)
81 /* Construct (1,2) IEEE floating_t from our random integer */
82 /* http://rgba.org/articles/sfrand/sfrand.htm */
83 unsigned long pmseed = (unsigned long)pthread_getspecific(seed_key);
84 pmseed *= 16807;
85 union { unsigned long ul; floating_t f; } p;
86 p.ul = ((pmseed & 0x007fffff) - 1) | 0x3f800000;
87 pthread_setspecific(seed_key, (void *)pmseed);
88 return p.f - 1.0f;
91 #endif