random.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:4k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * random.cxx
  3.  *
  4.  * Mersenne Twister random number generator.
  5.  * From Makoto Matsumoto and Takuji Nishimura.
  6.  *
  7.  * Portable Windows Library
  8.  *
  9.  * Copyright (c) 1993-2000 Equivalence Pty. Ltd.
  10.  *
  11.  * The contents of this file are subject to the Mozilla Public License
  12.  * Version 1.0 (the "License"); you may not use this file except in
  13.  * compliance with the License. You may obtain a copy of the License at
  14.  * http://www.mozilla.org/MPL/
  15.  *
  16.  * Software distributed under the License is distributed on an "AS IS"
  17.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  18.  * the License for the specific language governing rights and limitations
  19.  * under the License.
  20.  *
  21.  * The Original Code is Portable Windows Library.
  22.  *
  23.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  24.  *
  25.  * Based on code originally under the following license:
  26.  *
  27.  * This library is free software; you can redistribute it and/or   
  28.  * modify it under the terms of the GNU Library General Public     
  29.  * License as published by the Free Software Foundation; either    
  30.  * version 2 of the License, or (at your option) any later         
  31.  * version.                                                        
  32.  * This library is distributed in the hope that it will be useful, 
  33.  * but WITHOUT ANY WARRANTY; without even the implied warranty of  
  34.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.            
  35.  * See the GNU Library General Public License for more details.    
  36.  * You should have received a copy of the GNU Library General      
  37.  * Public License along with this library; if not, write to the    
  38.  * Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   
  39.  * 02111-1307  USA                                                 
  40.  * 
  41.  * Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura.       
  42.  * When you use this, send an email to: matumoto@math.keio.ac.jp   
  43.  * with an appropriate reference to your work.                     
  44.  *
  45.  * Contributor(s): ______________________________________.
  46.  *
  47.  * $Log: random.cxx,v $
  48.  * Revision 1.1  2000/02/17 12:05:02  robertj
  49.  * Added better random number generator after finding major flaws in MSVCRT version.
  50.  *
  51.  */
  52. #ifdef __GNUC__
  53. #pragma implementation "random.h"
  54. #endif
  55. #include <ptlib.h>
  56. #include <ptclib/random.h>
  57. /* Period parameters */  
  58. #define M 397
  59. #define MATRIX_A 0x9908b0df   /* constant vector a */
  60. #define UPPER_MASK 0x80000000 /* most significant w-r bits */
  61. #define LOWER_MASK 0x7fffffff /* least significant r bits */
  62. /* Tempering parameters */   
  63. #define TEMPERING_MASK_B 0x9d2c5680
  64. #define TEMPERING_MASK_C 0xefc60000
  65. #define TEMPERING_SHIFT_U(y)  (y >> 11)
  66. #define TEMPERING_SHIFT_S(y)  (y << 7)
  67. #define TEMPERING_SHIFT_T(y)  (y << 15)
  68. #define TEMPERING_SHIFT_L(y)  (y >> 18)
  69. ///////////////////////////////////////////////////////////////////////////////
  70. // PRandom
  71. PRandom::PRandom()
  72. {
  73.   SetSeed((DWORD)(time(NULL)+clock()));
  74. }
  75. PRandom::PRandom(DWORD seed)
  76. {
  77.   SetSeed(seed);
  78. }
  79. void PRandom::SetSeed(DWORD seed)
  80. {
  81.     /* setting initial seeds to mt[N] using         */
  82.     /* the generator Line 25 of Table 1 in          */
  83.     /* [KNUTH 1981, The Art of Computer Programming */
  84.     /*    Vol. 2 (2nd Ed.), pp102]                  */
  85.     mt[0] = seed & 0xffffffff;
  86.     for (mti = 1; mti < N; mti++)
  87.         mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
  88. }
  89. unsigned PRandom::Generate()
  90. {
  91.   unsigned long y;
  92.   static unsigned long mag01[2]={0x0, MATRIX_A};
  93.   /* mag01[x] = x * MATRIX_A  for x=0,1 */
  94.   if (mti >= N) { /* generate N words at one time */
  95.     int kk;
  96.     for (kk=0;kk<N-M;kk++) {
  97.       y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
  98.       mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
  99.     }
  100.     for (;kk<N-1;kk++) {
  101.       y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
  102.       mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
  103.     }
  104.     y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
  105.     mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
  106.     mti = 0;
  107.   }
  108.   y = mt[mti++];
  109.   y ^= TEMPERING_SHIFT_U(y);
  110.   y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
  111.   y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
  112.   y ^= TEMPERING_SHIFT_L(y);
  113.   return y; 
  114. }
  115. unsigned PRandom::Number()
  116. {
  117.   static PMutex mutex;
  118.   PWaitAndSignal wait(mutex);
  119.   static PRandom rand;
  120.   return rand;
  121. }
  122. // End Of File ///////////////////////////////////////////////////////////////