Mail Archives: djgpp-workers/1999/01/20/15:06:23
Here's the patch to add *rand48() to libc. I've received almost no
feedback (one comment from Eli), so I'm a little hesitant if this
should be added yet. Test it please.
Right,
MartinS
diff -ruN include.org/stdlib.h include/stdlib.h
--- include.org/stdlib.h Sat Jul 25 18:58:46 1998
+++ include/stdlib.h Wed Jan 6 20:56:42 1999
@@ -83,18 +83,27 @@
long double _atold(const char *_s);
long long atoll(const char *_s);
void cfree(void *_ptr);
+double drand48(void);
char * ecvtbuf(double _val, int _nd, int *_dp, int *_sn, char *_bf);
char * ecvt(double _val, int _nd, int *_dp, int *_sn);
+double erand48(unsigned short state[3]);
char * fcvtbuf(double _val, int _nd, int *_dp, int *_sn, char *_bf);
char * fcvt(double _val, int _nd, int *_dp, int *_sn);
char * gcvt(double _val, int _nd, char *_buf);
char * getpass(const char *_prompt);
int getlongpass(const char *_prompt, char *_buffer, int _max_len);
char * itoa(int value, char *buffer, int radix);
+long jrand48(unsigned short state[3]);
long long llabs(long long _i);
lldiv_t lldiv(long long _numer, long long _denom);
+void lcong48(unsigned short param[7]);
+unsigned long lrand48(void);
+long mrand48(void);
+unsigned long nrand48(unsigned short state[3]);
int putenv(const char *_val);
+unsigned short *seed48(unsigned short state_seed[3]);
int setenv(const char *_var, const char *_val, int _replace);
+void srand48(long seedval);
int stackavail(void);
long double _strtold(const char *_s, char **_endptr);
long long strtoll(const char *_s, char **_endptr, int _base);
diff -ruN src.org/libc/compat/stdlib/makefile src/libc/compat/stdlib/makefile
--- src.org/libc/compat/stdlib/makefile Sat Jul 25 18:58:44 1998
+++ src/libc/compat/stdlib/makefile Wed Jan 6 20:05:08 1999
@@ -20,6 +20,7 @@
SRC += fcvtbuf.c
SRC += fcvt.c
SRC += gcvt.c
+SRC += rand48.c
include $(TOP)/../makefile.inc
diff -ruN src.org/libc/compat/stdlib/rand48.c src/libc/compat/stdlib/rand48.c
--- src.org/libc/compat/stdlib/rand48.c Thu Jan 1 00:00:00 1970
+++ src/libc/compat/stdlib/rand48.c Mon Jan 11 09:20:40 1999
@@ -0,0 +1,186 @@
+/*
+ * File rand48.c.
+ *
+ * Copyright (C) 1999 Martin Str”mberg <ams AT ludd DOT luth DOT se>.
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact. There is no warranty on this software.
+ *
+ */
+
+#include "stdlib.h"
+
+#define RAND48_MULT0 (0xe66d)
+#define RAND48_MULT1 (0xdeec)
+#define RAND48_MULT2 (0x0005)
+#define RAND48_ADD (0x000b)
+
+static unsigned short internal_state[3] = {1, 0, 0};
+static unsigned short multiplier0 = RAND48_MULT0;
+static unsigned short multiplier1 = RAND48_MULT1;
+static unsigned short multiplier2 = RAND48_MULT2;
+static unsigned short additiver = RAND48_ADD;
+
+static void next(
+ unsigned short state[]
+ )
+{
+ unsigned short new_state[3];
+ unsigned long tmp;
+
+ tmp = state[0] * multiplier0 + additiver;
+ new_state[0] = (unsigned short)(tmp & 0xffff);
+
+ tmp = (tmp >> 8*sizeof(unsigned short))
+ + state[0] * multiplier1
+ + state[1] * multiplier0;
+ new_state[1] = (unsigned short)(tmp & 0xffff);
+
+ tmp = (tmp >> 8*sizeof(unsigned short))
+ + state[0] * multiplier2
+ + state[1] * multiplier1
+ + state[2] * multiplier0;
+ new_state[2] = (unsigned short)(tmp & 0xffff);
+
+ memcpy(state, new_state, 3*sizeof(unsigned short));
+}
+
+double drand48(void)
+{
+ return(erand48(internal_state));
+}
+
+double erand48(
+ unsigned short state[3]
+ )
+{
+ int i; /* Counter. */
+ double pot = 0.5; /* A potential of 0.5. */
+ double result = 0.0;
+
+ next(state);
+
+ for(i = 0; i < 8*sizeof(unsigned short); i++)
+ {
+ if( (state[2] << i) & 0x8000 )
+ {
+ result += pot;
+ }
+ pot /= 2.0;
+ if( (state[1] << i) & 0x8000 )
+ {
+ result += pot;
+ }
+ pot /= 2.0;
+ if( (state[0] << i) & 0x8000 )
+ {
+ result += pot;
+ }
+ pot /= 2.0;
+ }
+
+ return(result);
+
+}
+
+
+unsigned long lrand48(void)
+{
+ return(nrand48(internal_state));
+}
+
+
+unsigned long nrand48(
+ unsigned short state[3]
+ )
+{
+
+ next(state);
+ return( ((unsigned long)state[2]) * 0x8000
+ + ( ((unsigned long)state[1]) >> 1 )
+ );
+
+}
+
+
+long mrand48(void)
+{
+ return(jrand48(internal_state));
+}
+
+
+long jrand48(
+ unsigned short state[3]
+ )
+{
+
+ next(state);
+ if( (state[2] & 0x8000) )
+ {
+ return( -1.0 * ((long)(state[2] & 0x7fff)) * 0x10000 + ((unsigned long)state[1]) );
+ }
+ else
+ {
+ return( ((long)(state[2] & 0x7fff)) * 0x10000 + ((unsigned long)state[1]) );
+ }
+
+}
+
+void srand48(
+ long seedval
+ )
+{
+
+ /* Restore default multipliers and additiver. */
+ multiplier0 = RAND48_MULT0;
+ multiplier1 = RAND48_MULT1;
+ multiplier2 = RAND48_MULT2;
+ additiver = RAND48_ADD;
+
+ /* Setup the new state. */
+ internal_state[0] = 0x330e;
+ internal_state[1] = (seedval & 0xffff);
+ internal_state[2] = ( (seedval >> 16) & 0xffff);
+
+}
+
+unsigned short *seed48(
+ unsigned short state_seed[3]
+ )
+{
+ static unsigned short old_state[3];
+
+ /* Restore default multipliers and additiver. */
+ multiplier0 = RAND48_MULT0;
+ multiplier1 = RAND48_MULT1;
+ multiplier2 = RAND48_MULT2;
+ additiver = RAND48_ADD;
+
+ /* Remember old state. */
+ memcpy(old_state, internal_state, 3*sizeof(unsigned short));
+
+ /* Setup the new state. */
+ memcpy(internal_state, state_seed, 3*sizeof(unsigned short));
+
+ return(old_state);
+}
+
+void lcong48(
+ unsigned short param[7]
+ )
+{
+
+ /* Set the state. */
+ internal_state[0] = param[0];
+ internal_state[1] = param[1];
+ internal_state[2] = param[2];
+
+ /* Set the multipilers. */
+ multiplier0 = param[3];
+ multiplier1 = param[4];
+ multiplier2 = param[5];
+
+ /* Set the additiver. */
+ additiver = param[6];
+
+}
diff -ruN src.org/libc/compat/stdlib/rand48.txh src/libc/compat/stdlib/rand48.txh
--- src.org/libc/compat/stdlib/rand48.txh Thu Jan 1 00:00:00 1970
+++ src/libc/compat/stdlib/rand48.txh Sun Jan 10 16:56:16 1999
@@ -0,0 +1,80 @@
+@node rand48, random number
+@subheading Syntax
+
+@example
+#include <stdlib.h>
+
+double drand48(void);
+double erand48(unsigned short state[3]);
+unsigned long lrand48(void);
+unsigned long nrand48(unsigned short state[3]);
+long mrand48(void);
+long jrand48(unsigned short state[3]);
+void srand48(long seed);
+unsigned short *seed48(unsigned short state_seed[3]);
+void lcong48(unsigned short param[7]);
+@end example
+
+@subheading Description
+
+This is the family of *rand48 functions. The basis for these functions
+is the linear congruential formula X[n+1] = (a*X[n] + c) mod 2^48, n
+>= 0. a = 0x5deece66d and c = 0xb at start and after a call to either
+@code{srand48} or @code{seed48}. A call to @code{lcong48}
+changes a and c (and the internal state).
+
+@code{drand48} and @code{erand48} return @code{double}s uniformly
+distributed in the interval [0.0, 1.0).
+
+@code{lrand48} and @code{nrand48} return @code{unsigned long}s
+uniformly distributed in the interval [0, 2^31).
+
+@code{mrand48} and @code{jrand48} return @code{long}s uniformly
+distributed in the interval [-2^31, 2^31).
+
+@code{erand48}, @code{jrand48} and @code{nrand48} requires the
+state of the random generator to be passed.
+
+@code{drand48}, @code{lrand48} and @code{mrand48} uses an
+internal state (common with all three functions) which should be
+initialised with a call to one of the functions @code{srand48},
+@code{seed48} or @code{lcong48}.
+
+@code{srand48} sets the high order 32 bits to the argument
+@var{seed}. The low order 16 bits are set to the arbitrary value
+0x330e.
+
+@code{seed48} sets the internal state according to the argument
+@var{state_seed} (@var{state_seed[0]} is least significant). The
+previous state of the random generator is saved in an internal
+(static) buffer, to which a pointer is returned.
+
+@code{lcong48} sets the internal state to @var{param[0-2]}, a to
+@var{param[3-5]} (@var{param[0]} and @var{param[3]} are least
+significant) and c to @var{param[6]}.
+
+@subheading Return Value
+
+A random number.
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+int main(void)
+@{
+
+ srand48(time(NULL));
+ printf("%.12f is a random number in [0.0, 1.0).\n", drand48());
+
+ exit(0);
+@}
+
+@end example
- Raw text -