X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fmath%2Fsg_random.c;h=d9f6bcb78f9c8642abc3ab32c2c807cd370e00e1;hb=584ee1364f25e5c3795f9ff4633a792cba39bfc7;hp=31297e19829624cb94487c15b0a3cc413e17c3df;hpb=75911b6c643d8e5597565bc63c34bdc2009a037a;p=simgear.git diff --git a/simgear/math/sg_random.c b/simgear/math/sg_random.c index 31297e19..d9f6bcb7 100644 --- a/simgear/math/sg_random.c +++ b/simgear/math/sg_random.c @@ -2,7 +2,7 @@ // // Written by Curtis Olson, started July 1997. // -// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com +// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -14,16 +14,29 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. +// 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 02110-1301, USA. // // $Id$ +/* + * "Cleaned up" and simplified Mersenne Twister implementation. + * Vastly smaller and more easily understood and embedded. Stores the + * state in a user-maintained structure instead of static memory, so + * you can have more than one, or save snapshots of the RNG state. + * Lacks the "init_by_array()" feature of the original code in favor + * of the simpler 32 bit seed initialization. Lacks the floating + * point generator, which is an orthogonal problem not related to + * random number generation. Verified to be identical to the original + * MT199367ar code through the first 10M generated numbers. + */ + + + #ifdef HAVE_CONFIG_H -# include +# include #endif #include @@ -32,50 +45,70 @@ #include "sg_random.h" -#ifndef HAVE_RAND -# ifdef sgi -# undef RAND_MAX -# define RAND_MAX 2147483647 -# endif -#endif +// Structure for the random number functions. +mt random_seed; + +#define MT(i) mt->array[i] + +void mt_init(mt *mt, unsigned int seed) +{ + int i; + MT(0)= seed; + for(i=1; i> 30)) + i); + mt->index = MT_N+1; +} + +void mt_init_time_10(mt *mt) +{ + mt_init(mt, (unsigned int) time(NULL) / 600); +} -#ifdef __SUNPRO_CC - extern "C" { - long int random(); - void srandom(unsigned int seed); +unsigned int mt_rand32(mt *mt) +{ + unsigned int i, y; + if(mt->index >= MT_N) { + for(i=0; i>1) ^ (y&1 ? 0x9908b0df : 0); + } + mt->index = 0; } -#endif + y = MT(mt->index++); + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680; + y ^= (y << 15) & 0xefc60000; + y ^= (y >> 18); + return y; +} +double mt_rand(mt *mt) +{ + /* divided by 2^32-1 */ + return (double)mt_rand32(mt) * (1.0/4294967295.0); +} // Seed the random number generater with time() so we don't see the // same sequence every time void sg_srandom_time() { -#ifdef HAVE_RAND - srand(time(NULL)); -#else - srandom(time(NULL)); -#endif + mt_init(&random_seed, (unsigned int) time(NULL)); } +// Seed the random number generater with time() in 10 minute intervals +// so we get the same sequence within 10 minutes interval. +// This is useful for synchronizing two display systems. +void sg_srandom_time_10() { + mt_init(&random_seed, (unsigned int) time(NULL) / 600); +} // Seed the random number generater with your own seed so can set up // repeatable randomization. void sg_srandom( unsigned int seed ) { -#ifdef HAVE_RAND - srand( seed ); -#else - srandom( seed ); -#endif + mt_init(&random_seed, seed); } - // return a random number between [0.0, 1.0) double sg_random() { -#ifdef HAVE_RAND - return(rand() / (double)RAND_MAX); -#else - return(random() / (double)RAND_MAX); -#endif + return mt_rand(&random_seed); } -