1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
/* $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 <cstring>
using namespace Njn;
namespace {
const size_t r_off = 12;
long state [33] = {
static_cast <long> (0xd53f1852), static_cast <long> (0xdfc78b83), static_cast <long> (0x4f256096), static_cast <long> (0xe643df7),
static_cast <long> (0x82c359bf), static_cast <long> (0xc7794dfa), static_cast <long> (0xd5e9ffaa), static_cast <long> (0x2c8cb64a),
static_cast <long> (0x2f07b334), static_cast <long> (0xad5a7eb5), static_cast <long> (0x96dc0cde), static_cast <long> (0x6fc24589),
static_cast <long> (0xa5853646), static_cast <long> (0xe71576e2), static_cast <long> (0xdae30df), static_cast <long> (0xb09ce711),
static_cast <long> (0x5e56ef87), static_cast <long> (0x4b4b0082), static_cast <long> (0x6f4f340e), static_cast <long> (0xc5bb17e8),
static_cast <long> (0xd788d765), static_cast <long> (0x67498087), static_cast <long> (0x9d7aba26), static_cast <long> (0x261351d4),
static_cast <long> (0x411ee7ea), static_cast <long> (0x393a263), static_cast <long> (0x2c5a5835), static_cast <long> (0xc115fcd8),
static_cast <long> (0x25e9132c), static_cast <long> (0xd0c6e906), static_cast <long> (0xc2bc5b2d), static_cast <long> (0x6c065c98),
static_cast <long> (0x6e37bd55)};
long *rJ = &state [r_off];
long *rK = &state [sizeof state / sizeof *state - 1];
}
void Random::seed (long x)
{
register 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
{
register 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
}
|