Last active
December 18, 2015 19:09
-
-
Save qtxie/5831308 to your computer and use it in GitHub Desktop.
Mersenne Twister algorithm Red/System implementation -- generates a random number using the Mersenne Twister algorithm.
Reference http://code.google.com/p/c-standard-library/source/browse/src/internal/_rand.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Red/System [ | |
Title: "Mersenne Twister Random Function" | |
Author: "XieQ" | |
Tabs: 4 | |
Purpose: { | |
Generates a random number using the Mersenne Twister algorithm. | |
Reference http://code.google.com/p/c-standard-library/source/browse/src/internal/_rand.c | |
} | |
] | |
;-- Mersenne Twister magic numbers -- | |
#define state-size 624 | |
#define state-half-size 397 | |
#define high-mask 80000000h | |
#define low-mask 7FFFFFFFh | |
state-table: as int-ptr! allocate state-size * size? integer! | |
next-index: 0 | |
srand: func [ | |
seed [integer!] | |
/local c n | |
][ | |
state-table/1: seed | |
c: 1 | |
n: 1 | |
until [ | |
n: n + 1 | |
state-table/n: state-table/c >> 30 xor state-table/c * 1812433253 + c | |
c: c + 1 | |
n = state-size | |
] | |
] | |
rand: func [ | |
return: [integer!] | |
/local | |
c [integer!] | |
n [integer!] | |
state [integer!] | |
][ | |
c: 1 | |
n: 2 | |
;-- Refill rand state table if exhausted | |
if next-index = state-size [ | |
next-index: 0 | |
until [ | |
state: state-table/c and high-mask or (state-table/n and low-mask) | |
n: c - 1 + state-half-size % state-size + 1 ;-- need to plus one due to 1-base array | |
either state and 00000001h <> 0 [ ;-- state is odd | |
state-table/c: state >> 1 xor state-table/n xor 9908B0DFh | |
][ | |
state-table/c: state >> 1 xor state-table/n | |
] | |
c: c + 1 | |
n: c + 1 | |
c = state-size | |
] | |
c: state-half-size | |
n: state-size | |
state: state-table/n and high-mask or (state-table/1 and low-mask) | |
either state and 00000001h <> 0 [ | |
state-table/n: state >> 1 xor state-table/c xor 9908B0DFh | |
][ | |
state-table/n: state >> 1 xor state-table/c | |
] | |
] | |
next-index: next-index + 1 | |
state: state-table/next-index | |
;-- Add a little extra mixing | |
state: state >> 11 xor state | |
state: state << 7 and 9D2C5680h xor state | |
state: state << 15 and EFC60000h xor state | |
state: state >> 18 xor state | |
state | |
] | |
print "--Test--^/" | |
i: 0 | |
temp: 0 | |
srand 42 | |
while [i < 99999999][ | |
temp: rand % 999 | |
i: i + 1 | |
] | |
print-line rand % 999 | |
print-line rand % 999 | |
print-line rand % 999 | |
free as byte-ptr! state-table |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment