aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-07-04 19:51:15 -0700
committerPaul Eggert2011-07-04 19:51:15 -0700
commitd8ed26bd07abb23acc9c1879776f5afc44ed4874 (patch)
treeab5b8c578e2d209e3d1984a45260f38aa388fada /src
parentb768cdcd31e941af9a1ddce45da7e1482b494e77 (diff)
downloademacs-d8ed26bd07abb23acc9c1879776f5afc44ed4874.tar.gz
emacs-d8ed26bd07abb23acc9c1879776f5afc44ed4874.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog12
-rw-r--r--src/fns.c10
-rw-r--r--src/sysdep.c11
3 files changed, 26 insertions, 7 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 17a6179f356..9ad7da46ecf 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,15 @@
12011-07-05 Paul Eggert <eggert@cs.ucla.edu>
2
3 Random fixes. E.g., (random) never returned negative values.
4 * fns.c (Frandom): Use GET_EMACS_TIME for random seed, and add the
5 subseconds part to the entropy, as that's a bit more random.
6 Prefer signed to unsigned, since the signedness doesn't matter and
7 in general we prefer signed. When given a limit, use a
8 denominator equal to INTMASK + 1, not to VALMASK + 1, because the
9 latter isn't right if USE_2_TAGS_FOR_INTS.
10 * sysdep.c (get_random): Return a value in the range 0..INTMASK,
11 not 0..VALMASK. Don't discard "excess" bits that random () returns.
12
12011-07-04 Stefan Monnier <monnier@iro.umontreal.ca> 132011-07-04 Stefan Monnier <monnier@iro.umontreal.ca>
2 14
3 * textprop.c (text_property_stickiness): 15 * textprop.c (text_property_stickiness):
diff --git a/src/fns.c b/src/fns.c
index 5d2524d5cc2..0ca731ed331 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -79,10 +79,14 @@ Other values of LIMIT are ignored. */)
79{ 79{
80 EMACS_INT val; 80 EMACS_INT val;
81 Lisp_Object lispy_val; 81 Lisp_Object lispy_val;
82 EMACS_UINT denominator;
83 82
84 if (EQ (limit, Qt)) 83 if (EQ (limit, Qt))
85 seed_random (getpid () + time (NULL)); 84 {
85 EMACS_TIME t;
86 EMACS_GET_TIME (t);
87 seed_random (getpid () ^ EMACS_SECS (t) ^ EMACS_USECS (t));
88 }
89
86 if (NATNUMP (limit) && XFASTINT (limit) != 0) 90 if (NATNUMP (limit) && XFASTINT (limit) != 0)
87 { 91 {
88 /* Try to take our random number from the higher bits of VAL, 92 /* Try to take our random number from the higher bits of VAL,
@@ -92,7 +96,7 @@ Other values of LIMIT are ignored. */)
92 it's possible to get a quotient larger than n; discarding 96 it's possible to get a quotient larger than n; discarding
93 these values eliminates the bias that would otherwise appear 97 these values eliminates the bias that would otherwise appear
94 when using a large n. */ 98 when using a large n. */
95 denominator = ((EMACS_UINT) 1 << VALBITS) / XFASTINT (limit); 99 EMACS_INT denominator = (INTMASK + 1) / XFASTINT (limit);
96 do 100 do
97 val = get_random () / denominator; 101 val = get_random () / denominator;
98 while (val >= XFASTINT (limit)); 102 while (val >= XFASTINT (limit));
diff --git a/src/sysdep.c b/src/sysdep.c
index 3a73b1a467b..8b6939b91fe 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1783,7 +1783,8 @@ seed_random (long int arg)
1783} 1783}
1784 1784
1785/* 1785/*
1786 * Build a full Emacs-sized word out of whatever we've got. 1786 * Return a nonnegative random integer out of whatever we've got.
1787 * It contains enough bits to make a random (signed) Emacs fixnum.
1787 * This suffices even for a 64-bit architecture with a 15-bit rand. 1788 * This suffices even for a 64-bit architecture with a 15-bit rand.
1788 */ 1789 */
1789EMACS_INT 1790EMACS_INT
@@ -1791,9 +1792,11 @@ get_random (void)
1791{ 1792{
1792 EMACS_UINT val = 0; 1793 EMACS_UINT val = 0;
1793 int i; 1794 int i;
1794 for (i = 0; i < (VALBITS + RAND_BITS - 1) / RAND_BITS; i++) 1795 for (i = 0; i < (FIXNUM_BITS + RAND_BITS - 1) / RAND_BITS; i++)
1795 val = (val << RAND_BITS) ^ random (); 1796 val = (random () ^ (val << RAND_BITS)
1796 return val & (((EMACS_INT) 1 << VALBITS) - 1); 1797 ^ (val >> (BITS_PER_EMACS_INT - RAND_BITS)));
1798 val ^= val >> (BITS_PER_EMACS_INT - FIXNUM_BITS);
1799 return val & INTMASK;
1797} 1800}
1798 1801
1799#ifndef HAVE_STRERROR 1802#ifndef HAVE_STRERROR