mersenne.c
author celestar
Mon, 01 Jan 2007 16:07:21 +0000
branchcustombridgeheads
changeset 5621 6ce400c0a2f4
parent 2952 6a26eeda9679
permissions -rw-r--r--
(svn r7719) [cbh] - Codechange: KUDr and I have decided that our developemnt efforts went in the wrong direction, so revert all changes from 7686 onwards
2186
461a2aff3486 (svn r2701) Insert Id tags into all source files
tron
parents: 2075
diff changeset
     1
/* $Id$ */
461a2aff3486 (svn r2701) Insert Id tags into all source files
tron
parents: 2075
diff changeset
     2
2075
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     3
#include "stdafx.h"
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     4
#include "openttd.h"
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     5
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     6
#ifdef MERSENNE_TWISTER
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     7
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     8
// Source code for Mersenne Twister.
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
     9
// A Random number generator with much higher quality random numbers.
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    10
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    11
#define N              (624)                 // length of _mt_state vector
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    12
#define M              (397)                 // a period parameter
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    13
#define K              (0x9908B0DFU)         // a magic constant
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    14
#define hiBit(u)       ((u) & 0x80000000U)   // mask all but highest   bit of u
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    15
#define loBit(u)       ((u) & 0x00000001U)   // mask all but lowest    bit of u
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    16
#define loBits(u)      ((u) & 0x7FFFFFFFU)   // mask     the highest   bit of u
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    17
#define mixBits(u, v)  (hiBit(u)|loBits(v))  // move hi bit of u to hi bit of v
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    18
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    19
static uint32   _mt_state[N+1];     // _mt_state vector + 1 extra to not violate ANSI C
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    20
static uint32   *_mt_next;          // _mt_next random value is computed from here
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    21
static int      _mt_left = -1;      // can *_mt_next++ this many times before reloading
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    22
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    23
void SeedMT(uint32 seed)
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    24
{
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    25
    register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = _mt_state;
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    26
    register int    j;
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    27
2952
6a26eeda9679 (svn r3511) More whitespace ([FS#46] by Rubidium)
tron
parents: 2548
diff changeset
    28
    for (_mt_left=0, *s++=x, j=N; --j;
2075
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    29
        *s++ = (x*=69069U) & 0xFFFFFFFFU);
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    30
 }
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    31
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    32
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    33
static uint32 ReloadMT(void)
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    34
 {
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    35
    register uint32 *p0=_mt_state, *p2=_mt_state+2, *pM=_mt_state+M, s0, s1;
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    36
    register int    j;
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    37
2952
6a26eeda9679 (svn r3511) More whitespace ([FS#46] by Rubidium)
tron
parents: 2548
diff changeset
    38
    if (_mt_left < -1)
2075
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    39
        SeedMT(4357U);
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    40
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    41
    _mt_left=N-1, _mt_next=_mt_state+1;
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    42
2952
6a26eeda9679 (svn r3511) More whitespace ([FS#46] by Rubidium)
tron
parents: 2548
diff changeset
    43
    for (s0=_mt_state[0], s1=_mt_state[1], j=N-M+1; --j; s0=s1, s1=*p2++)
2075
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    44
        *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    45
2952
6a26eeda9679 (svn r3511) More whitespace ([FS#46] by Rubidium)
tron
parents: 2548
diff changeset
    46
    for (pM=_mt_state, j=M; --j; s0=s1, s1=*p2++)
2075
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    47
        *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    48
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    49
    s1=_mt_state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    50
    s1 ^= (s1 >> 11);
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    51
    s1 ^= (s1 <<  7) & 0x9D2C5680U;
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    52
    s1 ^= (s1 << 15) & 0xEFC60000U;
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    53
    return(s1 ^ (s1 >> 18));
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    54
 }
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    55
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    56
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    57
uint32 RandomMT(void)
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    58
{
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    59
	uint32 y;
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    60
2952
6a26eeda9679 (svn r3511) More whitespace ([FS#46] by Rubidium)
tron
parents: 2548
diff changeset
    61
	if (--_mt_left < 0)
2075
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    62
		return ReloadMT();
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    63
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    64
	y  = *_mt_next++;
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    65
	y ^= (y >> 11);
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    66
	y ^= (y <<  7) & 0x9D2C5680U;
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    67
	y ^= (y << 15) & 0xEFC60000U;
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    68
	return y ^ (y >> 18);
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    69
}
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    70
#else
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    71
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    72
void SeedMT(uint32 seed) {}
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    73
7f0ca01392db (svn r2585) - Fix [Makefile]: some small cleanups, remove warnings, and add mersenne to makefile (Luca)
Darkvater
parents: 2073
diff changeset
    74
#endif /* MERSENNE_TWISTER */