summaryrefslogtreecommitdiffstats
path: root/newlib/libc/stdlib/rand48.c
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2001-02-15 02:04:55 +0000
committerJeff Johnston <jjohnstn@redhat.com>2001-02-15 02:04:55 +0000
commitab4745dcb21ead97ebc469f93609a0b4a451f778 (patch)
tree78db58592891c02ef44134bae0b24b61d6311d94 /newlib/libc/stdlib/rand48.c
parentee2c7251d0069de6fe5e20f9295ddc0cfd41fb5c (diff)
downloadcygnal-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.c178
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;
+}