diff options
| author | Paul Eggert | 2011-07-04 19:51:15 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-07-04 19:51:15 -0700 |
| commit | d8ed26bd07abb23acc9c1879776f5afc44ed4874 (patch) | |
| tree | ab5b8c578e2d209e3d1984a45260f38aa388fada /src | |
| parent | b768cdcd31e941af9a1ddce45da7e1482b494e77 (diff) | |
| download | emacs-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/ChangeLog | 12 | ||||
| -rw-r--r-- | src/fns.c | 10 | ||||
| -rw-r--r-- | src/sysdep.c | 11 |
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 @@ | |||
| 1 | 2011-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 | |||
| 1 | 2011-07-04 Stefan Monnier <monnier@iro.umontreal.ca> | 13 | 2011-07-04 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 14 | ||
| 3 | * textprop.c (text_property_stickiness): | 15 | * textprop.c (text_property_stickiness): |
| @@ -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 | */ |
| 1789 | EMACS_INT | 1790 | EMACS_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 |