/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.12----------------------------------------------------------3Random numbers that return the same sequence on all platforms.4Implementation taken from the GNU C Library. The same copyright5applies.6----------------------------------------------------------78The GNU C Library is free software; you can redistribute it and/or9modify it under the terms of the GNU Lesser General Public10License as published by the Free Software Foundation; either11version 2.1 of the License, or (at your option) any later version.1213The GNU C Library is distributed in the hope that it will be useful,14but WITHOUT ANY WARRANTY; without even the implied warranty of15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU16Lesser General Public License for more details.1718You should have received a copy of the GNU Lesser General Public19License along with the GNU C Library; if not, write to the Free20Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA2102111-1307 USA. */222324#include <stdint.h>25#include "random.h"262728/* x**31 + x**3 + 1. */29#define TYPE_3 330#define BREAK_3 12831#define DEG_3 3132#define SEP_3 3333435static int32_t randtbl[DEG_3 + 1] =36{37TYPE_3,3839-1726662223, 379960547, 1735697613, 1040273694, 1313901226,401627687941, -179304937, -2073333483, 1780058412, -1989503057,41-615974602, 344556628, 939512070, -1249116260, 1507946756,42-812545463, 154635395, 1388815473, -1926676823, 525320961,43-1009028674, 968117788, -123449607, 1284210865, 435012392,44-2017506339, -911064859, -370259173, 1132637927, 1398500161,45-205601318,46};474849struct random_data50{51int32_t *fptr; /* Front pointer. */52int32_t *rptr; /* Rear pointer. */53int32_t *state; /* Array of state values. */54int rand_type; /* Type of random number generator. */55int rand_deg; /* Degree of random number generator. */56int rand_sep; /* Distance between front and rear. */57int32_t *end_ptr; /* Pointer behind state table. */58};5960static struct random_data rng_state =61{62.fptr = &randtbl[SEP_3 + 1],63.rptr = &randtbl[1],64.state = &randtbl[1],65.rand_type = TYPE_3,66.rand_deg = DEG_3,67.rand_sep = SEP_3,68.end_ptr = &randtbl[sizeof (randtbl) / sizeof (randtbl[0])]69};707172void portable_srand(unsigned int seed)73{74int type;75int32_t *state;76long int i;77int32_t word;78int32_t *dst;79int kc;8081/* printf("portable_srand: seed = %u\n", seed); */8283type = rng_state.rand_type;8485state = rng_state.state;86/* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */87if (seed == 0)88seed = 1;89state[0] = seed;9091dst = state;92word = seed;93kc = rng_state.rand_deg;94for (i = 1; i < kc; ++i)95{96/* This does:97state[i] = (16807 * state[i - 1]) % 2147483647;98but avoids overflowing 31 bits. */99long int hi = word / 127773;100long int lo = word % 127773;101word = 16807 * lo - 2836 * hi;102if (word < 0)103word += 2147483647;104*++dst = word;105}106107rng_state.fptr = &state[rng_state.rand_sep];108rng_state.rptr = &state[0];109kc *= 10;110while (--kc >= 0)111portable_rand();112}113114115int portable_rand(void)116{117int32_t *fptr = rng_state.fptr;118int32_t *rptr = rng_state.rptr;119int32_t *end_ptr = rng_state.end_ptr;120int32_t result;121122result = *fptr += *rptr;123/* Chucking least random bit. */124result = (result >> 1) & 0x7fffffff;125++fptr;126if (fptr >= end_ptr)127{128fptr = rng_state.state;129++rptr;130}131else132{133++rptr;134if (rptr >= end_ptr)135rptr = rng_state.state;136}137rng_state.fptr = fptr;138rng_state.rptr = rptr;139140/* printf("portable_rand: output = %d\n", result); */141142return result;143}144145146