/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
* http://www.gnu.org/software/gnugo/ for more information. *
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008 and 2009 by the Free Software Foundation. *
* 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 - version 3 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 *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License in file COPYING 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., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02111, USA. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* This is an implementation of the TGFSR (twisted generalized
* feedback shift register) random number generator TT800, which was
* Matsumoto, M. and Kurita, Y.: Twisted GFSR generators II.
* ACM Transactions on Modeling and Computer Simulations,
* Vol 4, No. 3, July 1994, pp 254--266
* The generator produces a pseudo-random sequence of 32 bit integers
* with period 2^800 - 1 and is reported to have excellent
* equidistribution properties, as well as being fast.
/* Algorithm parameters. */
static const unsigned int a
= 0x8ebfd028U
;
static const unsigned int b
= 0x2b5b2500U
;
static const unsigned int c
= 0xdb8b0000U
;
/* Global state for the random number generator. */
static unsigned int x
[N
];
/* Set when properly seeded. */
static int rand_initialized
= 0;
/* We use this to detect whether unsigned ints are bigger than 32
* bits. If they are we need to clear higher order bits, otherwise we
* can optimize by not doing the masking.
#define BIG_UINT (UINT_MAX > 0xffffffffU)
/* Iterate the TGFSR once to get a new state which can be used to
* produce another 25 random numbers.
for (i
= 0; i
< N
- m
; i
++)
x
[i
] = x
[i
+ m
] ^ (x
[i
] >> 1) ^ ((x
[i
] & 1) ? a
: 0);
x
[i
] = x
[i
+ m
- N
] ^ (x
[i
] >> 1) ^ ((x
[i
] & 1) ? a
: 0);
/* Produce a random number from the next word of the internal state.
assert(rand_initialized
); /* Abort. */
gg_srand(1); /* Initialize silently if assertions disabled. */
y
= x
[k
] ^ ((x
[k
] << s
) & b
);
/* Seed the random number generator. The first word of the internal
* state is set by the (lower) 32 bits of seed. The remaining 24 words
* are generated from the first one by a linear congruential pseudo
* FIXME: The constants in this generator has not been checked, but
* since they only are used to produce a very short sequence, which in
* turn only is a seed to a stronger generator, it probably doesn't
gg_srand(unsigned int seed
)
for (i
= 0; i
< N
; i
++) {
k
= N
-1; /* Force an immediate iteration of the TGFSR. */
/* Obtain one random integer value in the interval [0, 2^31-1].
return (int) (next_rand() & 0x7fffffff);
/* Obtain one random integer value in the interval [0, 2^32-1].
/* Obtain one random floating point value in the half open interval
* If the value is converted to a floating point type with less than
* 32 bits mantissa (or if the double type should happen to be
* unusually short), the value 1.0 may be attained.
return next_rand() * 2.328306436538696e-10;
/* Retrieve the internal state of the random generator.
gg_get_rand_state(struct gg_rand_state
*state
)
/* Set the internal state of the random number generator.
gg_set_rand_state(struct gg_rand_state
*state
)