emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r104956: Merge: Random fixes, e.g., (


From: Paul Eggert
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r104956: Merge: Random fixes, e.g., (random) never returned negative.
Date: Mon, 04 Jul 2011 19:53:27 -0700
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 104956 [merge]
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Mon 2011-07-04 19:53:27 -0700
message:
  Merge: Random fixes, e.g., (random) never returned negative.
modified:
  src/ChangeLog
  src/fns.c
  src/sysdep.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2011-07-04 18:31:29 +0000
+++ b/src/ChangeLog     2011-07-05 02:51:15 +0000
@@ -1,3 +1,15 @@
+2011-07-05  Paul Eggert  <address@hidden>
+
+       Random fixes.  E.g., (random) never returned negative values.
+       * fns.c (Frandom): Use GET_EMACS_TIME for random seed, and add the
+       subseconds part to the entropy, as that's a bit more random.
+       Prefer signed to unsigned, since the signedness doesn't matter and
+       in general we prefer signed.  When given a limit, use a
+       denominator equal to INTMASK + 1, not to VALMASK + 1, because the
+       latter isn't right if USE_2_TAGS_FOR_INTS.
+       * sysdep.c (get_random): Return a value in the range 0..INTMASK,
+       not 0..VALMASK.  Don't discard "excess" bits that random () returns.
+
 2011-07-04  Stefan Monnier  <address@hidden>
 
        * textprop.c (text_property_stickiness):

=== modified file 'src/fns.c'
--- a/src/fns.c 2011-07-04 12:22:39 +0000
+++ b/src/fns.c 2011-07-05 02:51:15 +0000
@@ -79,10 +79,14 @@
 {
   EMACS_INT val;
   Lisp_Object lispy_val;
-  EMACS_UINT denominator;
 
   if (EQ (limit, Qt))
-    seed_random (getpid () + time (NULL));
+    {
+      EMACS_TIME t;
+      EMACS_GET_TIME (t);
+      seed_random (getpid () ^ EMACS_SECS (t) ^ EMACS_USECS (t));
+    }
+
   if (NATNUMP (limit) && XFASTINT (limit) != 0)
     {
       /* Try to take our random number from the higher bits of VAL,
@@ -92,7 +96,7 @@
         it's possible to get a quotient larger than n; discarding
         these values eliminates the bias that would otherwise appear
         when using a large n.  */
-      denominator = ((EMACS_UINT) 1 << VALBITS) / XFASTINT (limit);
+      EMACS_INT denominator = (INTMASK + 1) / XFASTINT (limit);
       do
        val = get_random () / denominator;
       while (val >= XFASTINT (limit));

=== modified file 'src/sysdep.c'
--- a/src/sysdep.c      2011-06-25 08:40:38 +0000
+++ b/src/sysdep.c      2011-07-05 02:51:15 +0000
@@ -1783,7 +1783,8 @@
 }
 
 /*
- * Build a full Emacs-sized word out of whatever we've got.
+ * Return a nonnegative random integer out of whatever we've got.
+ * It contains enough bits to make a random (signed) Emacs fixnum.
  * This suffices even for a 64-bit architecture with a 15-bit rand.
  */
 EMACS_INT
@@ -1791,9 +1792,11 @@
 {
   EMACS_UINT val = 0;
   int i;
-  for (i = 0; i < (VALBITS + RAND_BITS - 1) / RAND_BITS; i++)
-    val = (val << RAND_BITS) ^ random ();
-  return val & (((EMACS_INT) 1 << VALBITS) - 1);
+  for (i = 0; i < (FIXNUM_BITS + RAND_BITS - 1) / RAND_BITS; i++)
+    val = (random () ^ (val << RAND_BITS)
+          ^ (val >> (BITS_PER_EMACS_INT - RAND_BITS)));
+  val ^= val >> (BITS_PER_EMACS_INT - FIXNUM_BITS);
+  return val & INTMASK;
 }
 
 #ifndef HAVE_STRERROR


reply via email to

[Prev in Thread] Current Thread [Next in Thread]