chxavrandom.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:3k
- /*============================================================================*
- *
- * (c) 1995-2002 RealNetworks, Inc. Patents pending. All rights reserved.
- *
- *============================================================================*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "chxavrandom.h"
- #include "chxavvector.h"
- const unsigned int RandomSequence::RandomMax = 0x7fffffff;
- const RandomSequence::LFG::SeqParams RandomSequence::LFG::zm_seqParams[] = {
- {7,3},
- {15,1},
- {31,3},
- {63,1}};
- RandomSequence::RandomSequence(unsigned int seed, int type) :
- m_type(type),
- m_lcg(seed)
- {
- if (type > 0)
- m_lfg = LFG(seed,type - 1);
- }
- unsigned int
- RandomSequence::Random()
- {
- unsigned int ret;
- if (m_type == 0)
- ret = m_lcg.Random();
- else
- ret = m_lfg.Random();
- return ret;
- }
- void
- RandomSequence::SRandom(unsigned int seed)
- {
- if (m_type == 0)
- m_lcg.SRandom(seed);
- else
- m_lfg.SRandom(seed);
- }
- inline
- RandomSequence::LCG::LCG(unsigned int seed):
- m_seed(seed)
- {
- // Seed cannot equal 0. Arbitrarily set it to 1 instead
- if (m_seed == 0)
- m_seed = 1;
- }
- inline
- unsigned int
- RandomSequence::LCG::Random()
- {
- m_seed = (1103515245 * m_seed + 12345) & RandomSequence::RandomMax;
- return m_seed;
- }
- inline
- void
- RandomSequence::LCG::SRandom(unsigned int seed)
- {
- if (seed == 0)
- /* Arbitrarily replace with 1 because 0 cannot be a seed */
- m_seed = 1;
- else
- m_seed = seed;
- }
- inline
- RandomSequence::LFG::LFG() :
- m_degree(0),
- m_sep(0),
- m_fptr(0),
- m_rptr(0),
- m_state(1)
- {}
- inline
- RandomSequence::LFG::LFG(unsigned int seed,int type):
- m_degree(zm_seqParams[type].m_degree),
- m_sep(zm_seqParams[type].m_seperation),
- m_state(zm_seqParams[type].m_degree)
- {
- SRandom(seed);
- }
- inline
- unsigned int
- RandomSequence::LFG::Random()
- {
- unsigned int val = m_state[m_fptr] += m_state[m_rptr];
-
- m_fptr++;
- if (m_fptr >= m_degree)
- {
- m_fptr = 0;
- ++m_rptr;
- }
- else
- {
- ++m_rptr;
- if (m_rptr >= m_degree)
- {
- m_rptr = 0;
- }
- }
-
- val = (val >> 1) & RandomSequence::RandomMax;
-
- return val;
- }
- inline
- void
- RandomSequence::LFG::SRandom(unsigned int seed)
- {
- StateGen randSeq(seed);
-
- m_state[0] = seed;
- int kc = m_degree;
- unsigned int* dst = (unsigned int*)m_state;
- for (int i = 1; i < kc; ++i)
- {
- int val = randSeq.Random();
- *++dst = val;
- }
-
- m_fptr = m_sep;
- m_rptr = 0;
- kc *= 10;
- while (--kc >= 0)
- {
- Random();
- }
- }
- inline
- RandomSequence::LFG::StateGen::StateGen(unsigned int seed):
- m_seed(seed)
- {
- // Seed cannot equal 0. Arbitrarily set it to 1 instead
- if (m_seed == 0)
- m_seed = 1;
- }
- inline
- unsigned int
- RandomSequence::LFG::StateGen::Random()
- {
- /* This does:
- state[i] = (16807 * state[-i-1]) % 2146483647
- but avoids overflowing 31 bits
- */
- unsigned int word = m_seed;
- unsigned int hi = word / 127773;
- unsigned int lo = word % 127773;
-
- word = 16807 * lo - 2836 * hi;
- if (word & 0x80000000)
- word = (word -1) & RandomSequence::RandomMax;
-
- m_seed = word;
-
- return m_seed;
- }