delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/01/09/08:00:11

From: Martin Str|mberg <ams AT ludd DOT luth DOT se>
Message-Id: <199901091259.NAA01314@sister.ludd.luth.se>
Subject: rand48 for libc
To: djgpp-workers AT delorie DOT com (DJGPP-WORKERS)
Date: Sat, 9 Jan 1999 13:59:28 +0100 (MET)
X-Mailer: ELM [version 2.4ME+ PL15 (25)]
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com

Here's the patch to add *rand48() functions to libc. This time with
documentation. 


Holmboe, Symphony 7,

							MartinS

diff -rNu 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 -rNu 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     Sat Jan  9 13:29:34 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 -rNu 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   Thu Jan  7 09:39:36 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
+@code{seed}. The low order 16 bits are set to the arbitrary value
+0x330e.
+
+@code{seed48()} sets the internal state according to the argument
+@code{state_seed} (@code{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 @code{param[0-2]}, a to
+@code{param[3-5]} (@code{param[0]} and @code{param[3]} are least
+significant) and c to @code{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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019