diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-01-20 10:55:18 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-01-20 10:55:18 +0000 |
commit | 70e9163c9c18e995515598085cb824e554eb7ae7 (patch) | |
tree | a42dc8b2a6c031354bf31472de888bfc8a060132 /lib/randint.c | |
parent | cbf5993c43f49281173f185863577d86bfac6eae (diff) | |
download | coreutils-tarball-master.tar.gz |
coreutils-8.25HEADcoreutils-8.25master
Diffstat (limited to 'lib/randint.c')
-rw-r--r-- | lib/randint.c | 149 |
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; + } } } |