summaryrefslogtreecommitdiff
path: root/lib/randint.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-01-20 10:55:18 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-01-20 10:55:18 +0000
commit70e9163c9c18e995515598085cb824e554eb7ae7 (patch)
treea42dc8b2a6c031354bf31472de888bfc8a060132 /lib/randint.c
parentcbf5993c43f49281173f185863577d86bfac6eae (diff)
downloadcoreutils-tarball-master.tar.gz
Diffstat (limited to 'lib/randint.c')
-rw-r--r--lib/randint.c149
1 files changed, 72 insertions, 77 deletions
diff --git a/lib/randint.c b/lib/randint.c
index 5ee738a..95c3c6d 100644
--- a/lib/randint.c
+++ b/lib/randint.c
@@ -1,11 +1,11 @@
/* Generate random integers.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006-2016 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify
+ This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,8 +13,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Paul Eggert. */
@@ -51,10 +50,6 @@ main (int argc, char **argv)
#include "xalloc.h"
-#ifndef MAX
-# define MAX(a,b) ((a) < (b) ? (b) : (a))
-#endif
-
/* A source of random data for generating random integers. */
struct randint_source
{
@@ -130,78 +125,78 @@ randint_genmax (struct randint_source *s, randint genmax)
randint randmax = s->randmax;
randint choices = genmax + 1;
- for (;;)
+ while (1)
{
if (randmax < genmax)
- {
- /* Calculate how many input bytes will be needed, and read
- the bytes. */
-
- size_t i = 0;
- randint rmax = randmax;
- unsigned char buf[sizeof randnum];
-
- do
- {
- rmax = shift_left (rmax) + UCHAR_MAX;
- i++;
- }
- while (rmax < genmax);
-
- randread (source, buf, i);
-
- /* Increase RANDMAX by appending random bytes to RANDNUM and
- UCHAR_MAX to RANDMAX until RANDMAX is no less than
- GENMAX. This may lose up to CHAR_BIT bits of information
- if shift_right (RANDINT_MAX) < GENMAX, but it is not
- worth the programming hassle of saving these bits since
- GENMAX is rarely that large in practice. */
-
- i = 0;
-
- do
- {
- randnum = shift_left (randnum) + buf[i];
- randmax = shift_left (randmax) + UCHAR_MAX;
- i++;
- }
- while (randmax < genmax);
- }
+ {
+ /* Calculate how many input bytes will be needed, and read
+ the bytes. */
+
+ size_t i = 0;
+ randint rmax = randmax;
+ unsigned char buf[sizeof randnum];
+
+ do
+ {
+ rmax = shift_left (rmax) + UCHAR_MAX;
+ i++;
+ }
+ while (rmax < genmax);
+
+ randread (source, buf, i);
+
+ /* Increase RANDMAX by appending random bytes to RANDNUM and
+ UCHAR_MAX to RANDMAX until RANDMAX is no less than
+ GENMAX. This may lose up to CHAR_BIT bits of information
+ if shift_right (RANDINT_MAX) < GENMAX, but it is not
+ worth the programming hassle of saving these bits since
+ GENMAX is rarely that large in practice. */
+
+ i = 0;
+
+ do
+ {
+ randnum = shift_left (randnum) + buf[i];
+ randmax = shift_left (randmax) + UCHAR_MAX;
+ i++;
+ }
+ while (randmax < genmax);
+ }
if (randmax == genmax)
- {
- s->randnum = s->randmax = 0;
- return randnum;
- }
+ {
+ s->randnum = s->randmax = 0;
+ return randnum;
+ }
else
- {
- /* GENMAX < RANDMAX, so attempt to generate a random number
- by taking RANDNUM modulo GENMAX+1. This will choose
- fairly so long as RANDNUM falls within an integral
- multiple of GENMAX+1; otherwise, LAST_USABLE_CHOICE < RANDNUM,
- so discard this attempt and try again.
-
- Since GENMAX cannot be RANDINT_MAX, CHOICES cannot be
- zero and there is no need to worry about dividing by
- zero. */
-
- randint excess_choices = randmax - genmax;
- randint unusable_choices = excess_choices % choices;
- randint last_usable_choice = randmax - unusable_choices;
- randint reduced_randnum = randnum % choices;
-
- if (randnum <= last_usable_choice)
- {
- s->randnum = randnum / choices;
- s->randmax = excess_choices / choices;
- return reduced_randnum;
- }
-
- /* Retry, but retain the randomness from the fact that RANDNUM fell
- into the range LAST_USABLE_CHOICE+1 .. RANDMAX. */
- randnum = reduced_randnum;
- randmax = unusable_choices - 1;
- }
+ {
+ /* GENMAX < RANDMAX, so attempt to generate a random number
+ by taking RANDNUM modulo GENMAX+1. This will choose
+ fairly so long as RANDNUM falls within an integral
+ multiple of GENMAX+1; otherwise, LAST_USABLE_CHOICE < RANDNUM,
+ so discard this attempt and try again.
+
+ Since GENMAX cannot be RANDINT_MAX, CHOICES cannot be
+ zero and there is no need to worry about dividing by
+ zero. */
+
+ randint excess_choices = randmax - genmax;
+ randint unusable_choices = excess_choices % choices;
+ randint last_usable_choice = randmax - unusable_choices;
+ randint reduced_randnum = randnum % choices;
+
+ if (randnum <= last_usable_choice)
+ {
+ s->randnum = randnum / choices;
+ s->randmax = excess_choices / choices;
+ return reduced_randnum;
+ }
+
+ /* Retry, but retain the randomness from the fact that RANDNUM fell
+ into the range LAST_USABLE_CHOICE+1 .. RANDMAX. */
+ randnum = reduced_randnum;
+ randmax = unusable_choices - 1;
+ }
}
}