diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2000-06-08 21:56:18 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2000-06-08 21:56:18 +0000 |
commit | 518882f3a2d5257253e126590994108e30c3d2ce (patch) | |
tree | e3d8474efdcb2ff84616969e20752615e566e9be /newlib/libc/stdlib/rand_r.c | |
parent | af76c2eed1153665f18e829be5d63794218ecf7d (diff) | |
download | cygnal-518882f3a2d5257253e126590994108e30c3d2ce.tar.gz cygnal-518882f3a2d5257253e126590994108e30c3d2ce.tar.bz2 cygnal-518882f3a2d5257253e126590994108e30c3d2ce.zip |
Thu Jun 8 17:54:00 2000 Jeff Johnston <jjohnstn@cygnus.com>
* libc/stdlib/rand_r.c: New algorithm that meets minimal
standard.
Diffstat (limited to 'newlib/libc/stdlib/rand_r.c')
-rw-r--r-- | newlib/libc/stdlib/rand_r.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/newlib/libc/stdlib/rand_r.c b/newlib/libc/stdlib/rand_r.c index 25307275f..437739ef5 100644 --- a/newlib/libc/stdlib/rand_r.c +++ b/newlib/libc/stdlib/rand_r.c @@ -1,7 +1,37 @@ #include <stdlib.h> +/* Pseudo-random generator based on Minimal Standard by + Lewis, Goodman, and Miller in 1969. + + I[j+1] = a*I[j] (mod m) + + where a = 16807 + m = 2147483647 + + Using Schrage's algorithm, a*I[j] (mod m) can be rewritten as: + + a*(I[j] mod q) - r*{I[j]/q} if >= 0 + a*(I[j] mod q) - r*{I[j]/q} + m otherwise + + where: {} denotes integer division + q = {m/a} = 127773 + r = m (mod a) = 2836 + + note that the seed value of 0 cannot be used in the calculation as + it results in 0 itself +*/ + int _DEFUN (rand_r, (seed), unsigned int *seed) { - return (((*seed) = (*seed) * 1103515245 + 12345) & RAND_MAX); + long k; + long s = (long)(*seed); + if (s == 0) + s = 0x12345987; + k = s / 127773; + s = 16807 * (s - k * 127773) - 2836 * k; + if (s < 0) + s += 2147483647; + (*seed) = (unsigned int)s; + return (int)(s & RAND_MAX); } |