Merge branch 'master' into boehm-demers-weiser-gc
[bpt/guile.git] / libguile / random.c
index ec00d5c..f5f706f 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999,2000,2001, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1999,2000,2001, 2003, 2005, 2006 Free Software Foundation, Inc.
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 
 
 /* Author: Mikael Djurfeldt <djurfeldt@nada.kth.se> */
 
-#if HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
 
@@ -75,13 +75,13 @@ scm_t_rng scm_the_rng;
 #define M_PI 3.14159265359
 #endif
 
-#if SCM_HAVE_T_INT64
+#if SCM_HAVE_T_UINT64
 
 unsigned long
 scm_i_uniform32 (scm_t_i_rstate *state)
 {
-  scm_t_int64 x = (scm_t_int64) A * state->w + state->c;
-  scm_t_int32 w = x & 0xffffffffUL;
+  scm_t_uint64 x = (scm_t_uint64) A * state->w + state->c;
+  scm_t_uint32 w = x & 0xffffffffUL;
   state->w = w;
   state->c = x >> 32L;
   return w;
@@ -106,12 +106,12 @@ scm_i_uniform32 (scm_t_i_rstate *state)
 unsigned long
 scm_i_uniform32 (scm_t_i_rstate *state)
 {
-  scm_t_int32 x1 = L (A) * L (state->w);
-  scm_t_int32 x2 = L (A) * H (state->w);
-  scm_t_int32 x3 = H (A) * L (state->w);
-  scm_t_int32 w = L (x1) + L (state->c);
-  scm_t_int32 m = H (x1) + L (x2) + L (x3) + H (state->c) + H (w);
-  scm_t_int32 x4 = H (A) * H (state->w);
+  scm_t_uint32 x1 = L (A) * L (state->w);
+  scm_t_uint32 x2 = L (A) * H (state->w);
+  scm_t_uint32 x3 = H (A) * L (state->w);
+  scm_t_uint32 w = L (x1) + L (state->c);
+  scm_t_uint32 m = H (x1) + L (x2) + L (x3) + H (state->c) + H (w);
+  scm_t_uint32 x4 = H (A) * H (state->w);
   state->w = w = (L (m) << 16) + L (w);
   state->c = H (x2) + H (x3) + x4 + H (m);
   return w;
@@ -122,8 +122,8 @@ scm_i_uniform32 (scm_t_i_rstate *state)
 void
 scm_i_init_rstate (scm_t_i_rstate *state, const char *seed, int n)
 {
-  scm_t_int32 w = 0L;
-  scm_t_int32 c = 0L;
+  scm_t_uint32 w = 0L;
+  scm_t_uint32 c = 0L;
   int i, m;
   for (i = 0; i < n; ++i)
     {
@@ -133,7 +133,7 @@ scm_i_init_rstate (scm_t_i_rstate *state, const char *seed, int n)
       else
         c += seed[i] << (8 * (m - 4));
     }
-  if ((w == 0 && c == 0) || (w == 0xffffffffUL && c == A - 1))
+  if ((w == 0 && c == 0) || (w == -1 && c == A - 1))
     ++c;
   state->w = w;
   state->c = c;
@@ -142,9 +142,10 @@ scm_i_init_rstate (scm_t_i_rstate *state, const char *seed, int n)
 scm_t_i_rstate *
 scm_i_copy_rstate (scm_t_i_rstate *state)
 {
-  scm_t_rstate *new_state = scm_malloc (scm_the_rng.rstate_size);
-  if (new_state == 0)
-    scm_memory_error ("rstate");
+  scm_t_rstate *new_state;
+
+  new_state = scm_gc_malloc_pointerless (scm_the_rng.rstate_size,
+                                        "random-state");
   return memcpy (new_state, state, scm_the_rng.rstate_size);
 }
 
@@ -156,9 +157,10 @@ scm_i_copy_rstate (scm_t_i_rstate *state)
 scm_t_rstate *
 scm_c_make_rstate (const char *seed, int n)
 {
-  scm_t_rstate *state = scm_malloc (scm_the_rng.rstate_size);
-  if (state == 0)
-    scm_memory_error ("rstate");
+  scm_t_rstate *state;
+
+  state = scm_gc_malloc_pointerless (scm_the_rng.rstate_size,
+                                    "random-state");
   state->reserved0 = 0;
   scm_the_rng.init_rstate (state, seed, n);
   return state;
@@ -318,12 +320,6 @@ make_rstate (scm_t_rstate *state)
   SCM_RETURN_NEWSMOB (scm_tc16_rstate, state);
 }
 
-static size_t
-rstate_free (SCM rstate)
-{
-  free (SCM_RSTATE (rstate));
-  return 0;
-}
 
 /*
  * Scheme level interface.
@@ -599,7 +595,6 @@ scm_init_random ()
   scm_the_rng = rng;
   
   scm_tc16_rstate = scm_make_smob_type ("random-state", 0);
-  scm_set_smob_free (scm_tc16_rstate, rstate_free);
 
   for (m = 1; m <= 0x100; m <<= 1)
     for (i = m >> 1; i < m; ++i)