chxavrandom.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 191 行

CPP
191
字号
/*============================================================================*
 *
 * (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;
}







⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?