chxavrandom.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:3k
源码类别:

Symbian

开发平台:

Visual C++

  1. /*============================================================================*
  2.  *
  3.  * (c) 1995-2002 RealNetworks, Inc. Patents pending. All rights reserved.
  4.  *
  5.  *============================================================================*/
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "chxavrandom.h"
  11. #include "chxavvector.h"
  12. const unsigned int RandomSequence::RandomMax = 0x7fffffff;
  13. const RandomSequence::LFG::SeqParams RandomSequence::LFG::zm_seqParams[] = { 
  14.     {7,3},
  15.     {15,1},
  16.     {31,3},
  17.     {63,1}};
  18. RandomSequence::RandomSequence(unsigned int seed, int type) :
  19.     m_type(type),
  20.     m_lcg(seed)
  21. {
  22.     if (type > 0)
  23. m_lfg = LFG(seed,type - 1);
  24. }
  25. unsigned int
  26. RandomSequence::Random()
  27. {
  28.     unsigned int ret;
  29.     if (m_type == 0)
  30. ret = m_lcg.Random();
  31.     else
  32. ret = m_lfg.Random();
  33.     return ret; 
  34. }
  35. void
  36. RandomSequence::SRandom(unsigned int seed)
  37. {
  38.     if (m_type == 0)
  39. m_lcg.SRandom(seed);
  40.     else
  41. m_lfg.SRandom(seed);
  42. }
  43. inline
  44. RandomSequence::LCG::LCG(unsigned int seed):
  45.     m_seed(seed)
  46. {
  47.     // Seed cannot equal 0. Arbitrarily set it to 1 instead
  48.     if (m_seed == 0)
  49. m_seed = 1;
  50. }
  51. inline
  52. unsigned int 
  53. RandomSequence::LCG::Random()
  54. {
  55.   m_seed = (1103515245 * m_seed + 12345) & RandomSequence::RandomMax;
  56.   return m_seed;
  57. }
  58. inline
  59. void 
  60. RandomSequence::LCG::SRandom(unsigned int seed)
  61. {
  62.   if (seed == 0)
  63.     /* Arbitrarily replace with 1 because 0 cannot be a seed */
  64.     m_seed = 1;
  65.   else
  66.     m_seed = seed;
  67. }
  68. inline
  69. RandomSequence::LFG::LFG() :
  70.     m_degree(0),
  71.     m_sep(0),
  72.     m_fptr(0),
  73.     m_rptr(0),
  74.     m_state(1)
  75. {}
  76. inline
  77. RandomSequence::LFG::LFG(unsigned int seed,int type): 
  78.     m_degree(zm_seqParams[type].m_degree),
  79.     m_sep(zm_seqParams[type].m_seperation),
  80.     m_state(zm_seqParams[type].m_degree)
  81. {   
  82.     SRandom(seed);
  83. }
  84. inline
  85. unsigned int
  86. RandomSequence::LFG::Random()
  87. {
  88.     unsigned int val = m_state[m_fptr] += m_state[m_rptr];
  89.     
  90.     m_fptr++;
  91.     if (m_fptr >= m_degree)
  92.     {
  93. m_fptr = 0;
  94. ++m_rptr;
  95.     }
  96.     else
  97.     {
  98. ++m_rptr;
  99. if (m_rptr >= m_degree)
  100. {
  101.     m_rptr = 0;
  102. }
  103.     }
  104.     
  105.     val = (val >> 1) & RandomSequence::RandomMax;
  106.  
  107.     return val;
  108. }
  109. inline
  110. void
  111. RandomSequence::LFG::SRandom(unsigned int seed)
  112. {
  113.     StateGen randSeq(seed);
  114.     
  115.     m_state[0] = seed;
  116.     int kc = m_degree;
  117.     unsigned int* dst = (unsigned int*)m_state;
  118.     for (int i = 1; i < kc; ++i)
  119.     {
  120. int val = randSeq.Random();
  121. *++dst = val; 
  122.     }
  123.     
  124.     m_fptr = m_sep;
  125.     m_rptr = 0;
  126.     kc *= 10;
  127.     while (--kc >= 0)
  128.     {
  129. Random();
  130.     }
  131. }
  132. inline
  133. RandomSequence::LFG::StateGen::StateGen(unsigned int seed):
  134.     m_seed(seed)
  135. {
  136.     // Seed cannot equal 0. Arbitrarily set it to 1 instead
  137.     if (m_seed == 0)
  138. m_seed = 1;
  139. }
  140. inline
  141. unsigned int 
  142. RandomSequence::LFG::StateGen::Random()
  143. {
  144.     /* This does:
  145.        state[i] = (16807 * state[-i-1]) % 2146483647 
  146.        but avoids overflowing 31 bits 
  147.     */
  148.     unsigned int word = m_seed;
  149.     unsigned int hi = word / 127773;
  150.     unsigned int lo = word % 127773;
  151.     
  152.     word = 16807 * lo - 2836 * hi;
  153.     if (word & 0x80000000)
  154. word = (word -1) & RandomSequence::RandomMax;
  155.     
  156.     m_seed = word;
  157.     
  158.     return m_seed;
  159. }