/* $Id: $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's offical duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * ===========================================================================*/ /***************************************************************************** File name: njn_random.cpp Author: John Spouge Contents: Additive random number generator // Modelled after "Algorithm A" in // D.E. Knuth (1981) The art of computer programming, volume 2, page 27. // 7/26/90 Warren Gish ******************************************************************************/ #include "njn_random.hpp" #include using namespace Njn; namespace { const size_t r_off = 12; long state [33] = { static_cast (0xd53f1852), static_cast (0xdfc78b83), static_cast (0x4f256096), static_cast (0xe643df7), static_cast (0x82c359bf), static_cast (0xc7794dfa), static_cast (0xd5e9ffaa), static_cast (0x2c8cb64a), static_cast (0x2f07b334), static_cast (0xad5a7eb5), static_cast (0x96dc0cde), static_cast (0x6fc24589), static_cast (0xa5853646), static_cast (0xe71576e2), static_cast (0xdae30df), static_cast (0xb09ce711), static_cast (0x5e56ef87), static_cast (0x4b4b0082), static_cast (0x6f4f340e), static_cast (0xc5bb17e8), static_cast (0xd788d765), static_cast (0x67498087), static_cast (0x9d7aba26), static_cast (0x261351d4), static_cast (0x411ee7ea), static_cast (0x393a263), static_cast (0x2c5a5835), static_cast (0xc115fcd8), static_cast (0x25e9132c), static_cast (0xd0c6e906), static_cast (0xc2bc5b2d), static_cast (0x6c065c98), static_cast (0x6e37bd55)}; long *rJ = &state [r_off]; long *rK = &state [sizeof state / sizeof *state - 1]; } void Random::seed (long x) { size_t i; state [0] = x; // linear congruential initializer for (i = 1; i < sizeof state / sizeof *state; ++i) { state [i] = 1103515245 * state [i - 1] + 12345; } rJ = &state [r_off]; rK = &state [sizeof state / sizeof *state - 1]; for (i = 0; i < 10 * sizeof state / sizeof *state; ++i) number (); } long Random::number () // uniform random x : 0 <= x <= exp2 (31) - 1 { long r; r = *rK; r += *rJ--; *rK-- = r; if (rK < state) { rK = &state [sizeof state / sizeof *state - 1]; } else if (rJ < state) { rJ = &state [sizeof state / sizeof *state - 1]; } return (r >> 1) &0x7fffffff; // discard the least-random bit }