diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2001-02-15 02:04:55 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2001-02-15 02:04:55 +0000 |
commit | ab4745dcb21ead97ebc469f93609a0b4a451f778 (patch) | |
tree | 78db58592891c02ef44134bae0b24b61d6311d94 /newlib/libc/stdlib/rand48.c | |
parent | ee2c7251d0069de6fe5e20f9295ddc0cfd41fb5c (diff) | |
download | cygnal-ab4745dcb21ead97ebc469f93609a0b4a451f778.tar.gz cygnal-ab4745dcb21ead97ebc469f93609a0b4a451f778.tar.bz2 cygnal-ab4745dcb21ead97ebc469f93609a0b4a451f778.zip |
2001-02-14 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
* libc/include/stdlib.h: Add declarations of rand48 functions and
their reentrant versions.
* libc/include/sys/reent.h: Move macros from rand48.h. Add
struct _rand48 for shared parameters of rand48 functions.
(struct _reent): Add a variable _r48 of struct _rand48.
(_REENT_INIT): Add _r48 initialization.
* libc/stdlib/Makefile.am (lib_a_SOURCES): Add rand48 functions.
(CHEWOUT_FILES): Add rand48.def.
* libc/stdlib/Makefile.am: Add dependencies for rand48 functions.
* libc/stdlib/Makefile.in: Regenerated.
* libc/stdlib/drand48.c (drand48, _drand48_r): Derived from the
NetBSD C library.
* libc/stdlib/erand48.c (erand48, _erand48_r): Ditto.
* libc/stdlib/jrand48.c (jrand48, _jrand48_r): Ditto.
* libc/stdlib/lcong48.c (lcong48, _lcong48_r): Ditto.
* libc/stdlib/lrand48.c (lrand48, _lrand48_r): Ditto.
* libc/stdlib/mrand48.c (mrand48, _mrand48_r): Ditto.
* libc/stdlib/nrand48.c (nrand48, _nrand48_r): Ditto.
* libc/stdlib/seed48.c (seed48, _seed48_r): Ditto.
* libc/stdlib/srand48.c (srand48, _srand48_r): Ditto.
* libc/stdlib/rand48.c (__dorand48): Ditto.
* libc/stdlib/rand48.h: Ditto, and modify declarations of global
parameters into macros referring them in the reentrant structure.
Diffstat (limited to 'newlib/libc/stdlib/rand48.c')
-rw-r--r-- | newlib/libc/stdlib/rand48.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/newlib/libc/stdlib/rand48.c b/newlib/libc/stdlib/rand48.c new file mode 100644 index 000000000..c65af12cd --- /dev/null +++ b/newlib/libc/stdlib/rand48.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + */ + +/* +FUNCTION + <<rand48>>, <<drand48>>, <<erand48>>, <<lrand48>>, <<nrand48>>, <<mrand48>>, <<jrand48>>, <<srand48>>, <<seed48>>, <<lcong48>> ---pseudo random number generators and initialization routines + +INDEX + rand48 +INDEX + drand48 +INDEX + erand48 +INDEX + lrand48 +INDEX + nrand48 +INDEX + mrand48 +INDEX + jrand48 +INDEX + srand48 +INDEX + seed48 +INDEX + lcong48 + +ANSI_SYNOPSIS + #include <stdlib.h> + double drand48(void); + double erand48(unsigned short <[xseed]>[3]); + long lrand48(void); + long nrand48(unsigned short <[xseed]>[3]); + long mrand48(void); + long jrand48(unsigned short <[xseed]>[3]); + void srand48(long <[seed]>); + unsigned short *seed48(unsigned short <[xseed]>[3]); + void lcong48(unsigned short <[p]>[7]); + +TRAD_SYNOPSIS + #include <stdlib.h> + double drand48(); + + double erand48(<[xseed]>) + unsigned short <[xseed]>[3]; + + long lrand48(); + + long nrand48(<[xseed]>) + unsigned short <[xseed]>[3]; + + long mrand48(); + + long jrand48(<[xseed]>) + unsigned short <[xseed]>[3]; + + void srand48(<[seed]>) + long <[seed]>; + + unsigned short *seed48(<[xseed]>) + unsigned short <[xseed]>[3]; + + void lcong48(<[p]>) + unsigned short <[p]>[7]; + +DESCRIPTION +The <<rand48>> family of functions generates pseudo-random numbers +using a linear congruential algorithm working on integers 48 bits in size. +The particular formula employed is +r(n+1) = (a * r(n) + c) mod m +where the default values are +for the multiplicand a = 0xfdeece66d = 25214903917 and +the addend c = 0xb = 11. The modulo is always fixed at m = 2 ** 48. +r(n) is called the seed of the random number generator. + +For all the six generator routines described next, the first +computational step is to perform a single iteration of the algorithm. + +<<drand48>> and <<erand48>> +return values of type double. The full 48 bits of r(n+1) are +loaded into the mantissa of the returned value, with the exponent set +such that the values produced lie in the interval [0.0, 1.0]. + +<<lrand48>> and <<nrand48>> +return values of type long in the range +[0, 2**31-1]. The high-order (31) bits of +r(n+1) are loaded into the lower bits of the returned value, with +the topmost (sign) bit set to zero. + +<<mrand48>> and <<jrand48>> +return values of type long in the range +[-2**31, 2**31-1]. The high-order (32) bits of +r(n+1) are loaded into the returned value. + +<<drand48>>, <<lrand48>>, and <<mrand48>> +use an internal buffer to store r(n). For these functions +the initial value of r(0) = 0x1234abcd330e = 20017429951246. + +On the other hand, <<erand48>>, <<nrand48>>, and <<jrand48>> +use a user-supplied buffer to store the seed r(n), +which consists of an array of 3 shorts, where the zeroth member +holds the least significant bits. + +All functions share the same multiplicand and addend. + +<<srand48>> is used to initialize the internal buffer r(n) of +<<drand48>>, <<lrand48>>, and <<mrand48>> +such that the 32 bits of the seed value are copied into the upper 32 bits +of r(n), with the lower 16 bits of r(n) arbitrarily being set to 0x330e. +Additionally, the constant multiplicand and addend of the algorithm are +reset to the default values given above. + +<<seed48>> also initializes the internal buffer r(n) of +<<drand48>>, <<lrand48>>, and <<mrand48>>, +but here all 48 bits of the seed can be specified in an array of 3 shorts, +where the zeroth member specifies the lowest bits. Again, +the constant multiplicand and addend of the algorithm are +reset to the default values given above. +<<seed48>> returns a pointer to an array of 3 shorts which contains +the old seed. +This array is statically allocated, thus its contents are lost after +each new call to <<seed48>>. + +Finally, <<lcong48>> allows full control over the multiplicand and +addend used in <<drand48>>, <<erand48>>, <<lrand48>>, <<nrand48>>, +<<mrand48>>, and <<jrand48>>, +and the seed used in <<drand48>>, <<lrand48>>, and <<mrand48>>. +An array of 7 shorts is passed as parameter; the first three shorts are +used to initialize the seed; the second three are used to initialize the +multiplicand; and the last short is used to initialize the addend. +It is thus not possible to use values greater than 0xffff as the addend. + +Note that all three methods of seeding the random number generator +always also set the multiplicand and addend for any of the six +generator calls. + +For a more powerful random number generator, see <<random>>. + +PORTABILITY +SUS requires these functions. + +No supporting OS subroutines are required. +*/ + +#include "rand48.h" + +void +_DEFUN (__dorand48, (r, xseed), + struct _reent *r _AND + unsigned short xseed[3]) +{ + unsigned long accu; + unsigned short temp[2]; + + accu = (unsigned long) __rand48_mult[0] * (unsigned long) xseed[0] + + (unsigned long) __rand48_add; + temp[0] = (unsigned short) accu; /* lower 16 bits */ + accu >>= sizeof(unsigned short) * 8; + accu += (unsigned long) __rand48_mult[0] * (unsigned long) xseed[1] + + (unsigned long) __rand48_mult[1] * (unsigned long) xseed[0]; + temp[1] = (unsigned short) accu; /* middle 16 bits */ + accu >>= sizeof(unsigned short) * 8; + accu += __rand48_mult[0] * xseed[2] + __rand48_mult[1] * xseed[1] + __rand48_mult[2] * xseed[0]; + xseed[0] = temp[0]; + xseed[1] = temp[1]; + xseed[2] = (unsigned short) accu; +} |