/** * @file tinymt32.c * * @brief Tiny Mersenne Twister only 127 bit internal state * * @author Mutsuo Saito (Hiroshima University) * @author Makoto Matsumoto (The University of Tokyo) * * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto, * Hiroshima University and The University of Tokyo. * All rights reserved. * * The 3-clause BSD License is applied to this software, see * LICENSE.txt */ /* Note: this is a stripped-down version of TinyMT that only includes the 32-bit integer generator. For the full version, please see . */ #include "tinymt32.h" #define TINYMT32_SH0 1 #define TINYMT32_SH1 10 #define TINYMT32_SH8 8 #define TINYMT32_MASK 0x7fffffff /** * This function changes internal state of tinymt32. * Users should not call this function directly. * @param random tinymt internal status */ static void tinymt32_next_state(tinymt32_t * random) { uint32_t x; uint32_t y; y = random->status[3]; x = (random->status[0] & TINYMT32_MASK) ^ random->status[1] ^ random->status[2]; x ^= (x << TINYMT32_SH0); y ^= (y >> TINYMT32_SH0) ^ x; random->status[0] = random->status[1]; random->status[1] = random->status[2]; random->status[2] = x ^ (y << TINYMT32_SH1); random->status[3] = y; random->status[1] ^= -((int32_t)(y & 1)) & random->mat1; random->status[2] ^= -((int32_t)(y & 1)) & random->mat2; } /** * This function outputs 32-bit unsigned integer from internal state. * Users should not call this function directly. * @param random tinymt internal status * @return 32-bit unsigned pseudorandom number */ static uint32_t tinymt32_temper(tinymt32_t * random) { uint32_t t0, t1; t0 = random->status[3]; #if defined(LINEARITY_CHECK) t1 = random->status[0] ^ (random->status[2] >> TINYMT32_SH8); #else t1 = random->status[0] + (random->status[2] >> TINYMT32_SH8); #endif t0 ^= t1; t0 ^= -((int32_t)(t1 & 1)) & random->tmat; return t0; } /** * This function outputs 32-bit unsigned integer from internal state. * @param random tinymt internal status * @return 32-bit unsigned integer r (0 <= r < 2^32) */ uint32_t tinymt32_generate_uint32(tinymt32_t * random) { tinymt32_next_state(random); return tinymt32_temper(random); } #define MIN_LOOP 8 #define PRE_LOOP 8 /** * This function certificate the period of 2^127-1. * @param random tinymt state vector. */ static void period_certification(tinymt32_t * random) { if ((random->status[0] & TINYMT32_MASK) == 0 && random->status[1] == 0 && random->status[2] == 0 && random->status[3] == 0) { random->status[0] = 'T'; random->status[1] = 'I'; random->status[2] = 'N'; random->status[3] = 'Y'; } } /** * This function initializes the internal state array with a 32-bit * unsigned integer seed. * @param random tinymt state vector. * @param seed a 32-bit unsigned integer used as a seed. */ void tinymt32_init(tinymt32_t * random, uint32_t seed) { random->status[0] = seed; random->status[1] = random->mat1; random->status[2] = random->mat2; random->status[3] = random->tmat; for (int i = 1; i < MIN_LOOP; i++) { random->status[i & 3] ^= i + UINT32_C(1812433253) * (random->status[(i - 1) & 3] ^ (random->status[(i - 1) & 3] >> 30)); } period_certification(random); for (int i = 0; i < PRE_LOOP; i++) { tinymt32_next_state(random); } }