From: Paul Eggert Date: Wed, 19 Mar 2014 21:14:32 +0000 (-0700) Subject: * fns.c (Frandom): Fix rare bug where the result isn't random. X-Git-Tag: emacs-24.3.90~145 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=d16ae6228826c561bdb3701bd65d7517bd9e30d5;p=emacs.git * fns.c (Frandom): Fix rare bug where the result isn't random. --- diff --git a/src/ChangeLog b/src/ChangeLog index 06e4c3291b5..f7f4a5f03b2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,7 @@ 2014-03-19 Paul Eggert + * fns.c (Frandom): Fix rare bug where the result isn't random. + Fix porting inconsistency about rounding to even. * floatfns.c (emacs_rint) [!HAVE_RINT]: Round to even. This way, the unusual !HAVE_RINT case acts like the usual diff --git a/src/fns.c b/src/fns.c index 7b3d41d5374..499e4b490a6 100644 --- a/src/fns.c +++ b/src/fns.c @@ -79,8 +79,17 @@ See Info node `(elisp)Random Numbers' for more details. */) seed_random (SSDATA (limit), SBYTES (limit)); val = get_random (); - if (NATNUMP (limit) && XFASTINT (limit) != 0) - val %= XFASTINT (limit); + if (INTEGERP (limit) && 0 < XINT (limit)) + while (true) + { + /* Return the remainder, except reject the rare case where + get_random returns a number so close to INTMASK that the + remainder isn't random. */ + EMACS_INT remainder = val % XINT (limit); + if (val - remainder <= INTMASK - XINT (limit) + 1) + return make_number (remainder); + val = get_random (); + } return make_number (val); }