zoukankan      html  css  js  c++  java
  • 随机数生成器

        在项目开发中,有时需要用到随机数生成器。用Win自带的接口或项目所依赖的底层模块(如:cocos2d-x引擎中的CC_RANDOM_0_1之类的)的确也能生成相应的随机数。但它们有一定的局限性。Win自带的API不支持跨平台,cocos2d-x引擎支持的随机数服务端就“没办法用”(其实用是可以用,但一般我们不会这么用。原因就好比:你开发一个手游项目时,让客户端引入boost库一个道理)。所以最好是能够有一个随机数生成算法,不但能生成随机数,还能支持跨平台,并且库不能太大,效率要能跟的上。还有最最重要的一点:必需要能够“重现”(所库能重现,是指相同的初始化输入需要能够得到相同的结果输出)。这点非常重要,因为在有些项目中,特别如游戏项目中,对于战斗是经常需要重放的。如果不能保证这点,则录像就完法使用随机数,进而导致战斗与录像必不一致。下面是个符合上述限制要求的一个不错的随机数生成器库可供参考使用:

      1 class mtrandom {
      2 public:
      3     mtrandom() :
      4       left(1) {
      5           init();
      6       }
      7       explicit mtrandom(unsigned int seed) :
      8       left(1) {
      9           init(seed);
     10       }
     11       mtrandom(unsigned int* init_key, int key_length) :
     12       left(1) {
     13           int i = 1, j = 0;
     14           int k = N > key_length ? N : key_length;
     15           init();
     16           for (; k; --k) {
     17               state[i] = (state[i] ^ ((state[i - 1] ^ (state[i - 1] >> 30))
     18                   * 1664525UL)) + init_key[j] + j; // non linear
     19               state[i] &= 4294967295UL;
     20               ++i;
     21               ++j;
     22               if (i >= N) {
     23                   state[0] = state[N - 1];
     24                   i = 1;
     25               }
     26               if (j >= key_length)
     27                   j = 0;
     28           }
     29           for (k = N - 1; k; --k) {
     30               state[i] = (state[i] ^ ((state[i - 1] ^ (state[i - 1] >> 30))
     31                   * 1566083941UL)) - i;
     32               state[i] &= 4294967295UL;
     33               ++i;
     34               if (i >= N) {
     35                   state[0] = state[N - 1];
     36                   i = 1;
     37               }
     38           }
     39           state[0] = 2147483648UL;
     40       }
     41       void reset(unsigned int rs) {
     42           init(rs);
     43           next_state();
     44       }
     45       unsigned int rand() {
     46           unsigned int y;
     47           if (0 == --left)
     48               next_state();
     49           y = *next++;
     50           y ^= (y >> 11);
     51           y ^= (y << 7) & 0x9d2c5680UL;
     52           y ^= (y << 15) & 0xefc60000UL;
     53           y ^= (y >> 18);
     54           return y;
     55       }
     56       int getRandInt(int min, int max)
     57       {
     58           if (min == max)
     59               return min;
     60           if (min > max)
     61               return rand() % (min - max + 1) + max;
     62           else
     63               return rand() % (max - min + 1) + min;
     64       }
     65       double real() {
     66           return (double) rand() / 0xffffffffUL;
     67       }
     68       double res53() {
     69           unsigned int a = rand() >> 5, b = rand() >> 6;
     70           return (a * 67108864.0 + b) / 9007199254740992.0;
     71       }
     72       void init(unsigned int seed = 19650218UL) {
     73           state[0] = seed & 4294967295UL;
     74           for (int j = 1; j < N; ++j) {
     75               state[j] = (1812433253UL * (state[j - 1] ^ (state[j - 1] >> 30))
     76                   + j);
     77               state[j] &= 4294967295UL; // for >32 bit machines
     78           }
     79       }
     80 private:
     81     void next_state() {
     82         unsigned int* p = state;
     83         int i;
     84         for (i = N - M + 1; --i; ++p)
     85             *p = (p[M] ^ twist(p[0], p[1]));
     86         for (i = M; --i; ++p)
     87             *p = (p[M - N] ^ twist(p[0], p[1]));
     88         *p = p[M - N] ^ twist(p[0], state[0]);
     89         left = N;
     90         next = state;
     91     }
     92     unsigned int mixbits(unsigned int u, unsigned int v) const {
     93         return (u & 2147483648UL) | (v & 2147483647UL);
     94     }
     95     unsigned int twist(unsigned int u, unsigned int v) const {
     96         return ((mixbits(u, v) >> 1) ^ (v & 1UL ? 2567483615UL : 0UL));
     97     }
     98     static const int N = 624, M = 397;
     99     unsigned int state[N];
    100     unsigned int left;
    101     unsigned int* next;
    102 };
    mtrandom 封装

        下面是先前的一个框架中对其使用的封装:

     1 /******************************************************************************
     2 
     3                            === I'm jacc.kim ===
     4                               
     5     创建日期:  2016年1月14日 8时51分
     6     文件名称:  GFRandomCreator.h
     7     说    明:  随机数生成器
     8 
     9     当前版本:  1.00
    10     作    者:  jacc.kim
    11     概    述:  
    12 
    13 ******************************************************************************/
    14 #pragma once
    15 
    16 #include "Framework/Foundation/GFHeader.h"
    17 #include "Framework/ThirdParty/random/mtrandom.h"
    18 
    19 NSGF_BEGIN
    20 
    21 /******************************************************************************
    22  * create   : (jacc.kim) [1-14-2016]
    23  * summary  : class GFRandomCreator.随机数生成器
    24 ******************************************************************************/
    25 class GFRandomCreator
    26 {
    27 public:
    28     // 设置种子
    29     void                        setSeed(const GFuint32 unSeed);
    30 
    31     // 随机生成一个数.
    32     const GFuint32              rand();
    33 
    34     // 生成一个值在某个范围内的随机数.
    35     const GFint32               randRange(const GFint32 nMinValue, const GFint32 nMaxValue);
    36 
    37 public:
    38     GFRandomCreator();
    39     ~GFRandomCreator();
    40 
    41 protected:
    42     GFRandomCreator(const GFRandomCreator&) DELETE_METHOD;
    43     GFRandomCreator& operator=(const GFRandomCreator&) DELETE_METHOD;
    44 
    45 private:
    46     mtrandom                    m_RandInstance;
    47 
    48 };//class GFRandomCreator
    49 
    50 NSGF_END
    GFRandomCreator.h文件
     1 #include "Framework/Foundation/GFRandomCreator.h"
     2 
     3 NSGF_BEGIN
     4 
     5 ///////////////////////////////////////////////////////////////////////////////
     6 // class GFRandomCreator
     7 GFRandomCreator::GFRandomCreator() {
     8 
     9 }
    10 
    11 GFRandomCreator::~GFRandomCreator() {
    12 
    13 }
    14 
    15 void GFRandomCreator::setSeed(const GFuint32 unSeed) {
    16     m_RandInstance.reset(unSeed);
    17 }
    18 
    19 const GFuint32 GFRandomCreator::rand() {
    20     return m_RandInstance.rand();
    21 }
    22 
    23 const GFint32 GFRandomCreator::randRange(const GFint32 nMinValue, const GFint32 nMaxValue) {
    24     return m_RandInstance.getRandInt(nMinValue, nMaxValue);
    25 }
    26 
    27 NSGF_END
    GFRandomCreator.cpp文件
  • 相关阅读:
    windows使用pipenv创建虚拟环境报错UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 4: in...
    mysql监控工具sqlprofiler,类似sqlserver的profiler工具安装(一)
    [转]linux awk命令详解
    navicat for mysql 如何设置字段唯一
    linux硬链接与软链接
    linux后台运行和关闭、查看后台任务
    测试覆盖率的基本策略
    【Unity Shader】二、顶点函数(vertex)和片元函数(fragment)传递数据,及各阶段可使用的语义(semantic)
    【Unity Shader】一、顶点函数(vertex)和片元函数(fragment)
    Unity Shader学习资料
  • 原文地址:https://www.cnblogs.com/tongy0/p/5662345.html
Copyright © 2011-2022 走看看