游戏开发论坛

 找回密码
 立即注册
搜索
12
返回列表 发新帖
楼主: xxp1234

我写的一个随机数函数,非常容易理解,有毛病大家PP

[复制链接]

13

主题

66

帖子

85

积分

注册会员

Rank: 2

积分
85
发表于 2004-3-14 17:33:00 | 显示全部楼层

Re:我写的一个随机数函数,非常容易理解,有毛病大家PP

我是新手, 请问  我这个随机数 和 1楼的 有什么区别???
他的好在什么地方????

int main()
{

   long i;
   srand( (unsigned)time( NULL ) );
  
   for (;;)
   {

          i = rand();  
      
            cout << i << endl;
   }

}

0

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2004-3-14 18:48:00 | 显示全部楼层

Re:我写的一个随机数函数,非常容易理解,有毛病大家PP

《构建安全的软件》——第十章 随机与惟定

24

主题

161

帖子

179

积分

注册会员

Rank: 2

积分
179
 楼主| 发表于 2004-3-15 08:55:00 | 显示全部楼层

Re:我写的一个随机数函数,非常容易理解,有毛病大家PP

写这个函数就是为了在很短的时间内不同对象在调用它时可取不同的随机数,否则我写这干吗呀?

随机数的范围可以自己确定,这个函数只给出了最大的范围[0,rand_max];

运行多次,没有报异常

至于分布是否均匀,仅从感觉上是可以的了,只是懒得写统计函数

24

主题

161

帖子

179

积分

注册会员

Rank: 2

积分
179
 楼主| 发表于 2004-5-31 08:38:00 | 显示全部楼层

Re:我写的一个随机数函数,非常容易理解,有毛病大家PP

这个函数非常非常昂贵,只适用于非实时:(

85

主题

824

帖子

878

积分

高级会员

Rank: 4

积分
878
QQ
发表于 2004-5-31 09:12:00 | 显示全部楼层

Re:我写的一个随机数函数,非常容易理解,有毛病大家PP

需要每次都srand()吗?
似乎没必要吧

0

主题

6

帖子

6

积分

新手上路

Rank: 1

积分
6
QQ
发表于 2004-5-31 09:54:00 | 显示全部楼层

Re:我写的一个随机数函数,非常容易理解,有毛病大家PP

这个是ACE带的一个例子,用于产生随机数,我正在用,很好。


/**********************************************************************
isaac.h
the class is used to pruduct random numbers.
**********************************************************************/
#ifndef __ISAAC_HPP
#define __ISAAC_HPP


/*

    C++ TEMPLATE VERSION OF Robert J. Jenkins Jr.'s
    ISAAC Random Number Generator.

    Ported from vanilla C to to template C++ class
    by Quinn Tyler Jackson on 16-23 July 1998.

        quinn@qtj.net

    The function for the expected period of this
    random number generator, according to Jenkins is:

        f(a,b) = 2**((a+b*(3+2^^a)-1)

        (where a is ALPHA and b is bitwidth)
        
    So, for a bitwidth of 32 and an ALPHA of 8,
    the expected period of ISAAC is:

        2^^(8+32*(3+2^^8)-1) = 2^^8295

    Jackson has been able to run implementations
    with an ALPHA as high as 16, or

        2^^2097263

*/


#ifndef __ISAAC64
   //typedef unsigned long int UINT32;
   const UINT32 GOLDEN_RATIO = UINT32(0x9e3779b9);
   typedef UINT32 ISAAC_INT;
#else   // __ISAAC64
typedef unsigned __int64 UINT64;
const UINT64 GOLDEN_RATIO = UINT64(0x9e3779b97f4a7c13);
typedef UINT64 ISAAC_INT;
#endif  // __ISAAC64


template <int ALPHA = (8), class T = ISAAC_INT>
   class QTIsaac
   {
   public:
   
      typedef unsigned char byte;
   
      struct randctx
      {
         randctx(void)
         {
            randrsl = (T*)::malloc(N * sizeof(T));
            randmem = (T*)::malloc(N * sizeof(T));
         }
      
         ~randctx(void)
         {
            ::free((void*)randrsl);
            ::free((void*)randmem);
         }
      
         T randcnt;
         T* randrsl;
         T* randmem;
         T randa;
         T randb;
         T randc;
      };
   
      QTIsaac(T a = 0, T b = 0, T c = 0);
      virtual ~QTIsaac(void);
   
      T rand(void);
      virtual void randinit(randctx* ctx, bool bUseSeed);
      virtual void srand(T a = 0, T b = 0, T c = 0, T* s = 0);
   
      enum {N = (1<<ALPHA)};
   
   protected:
   
      virtual void isaac(randctx* ctx);
   
      T ind(T* mm, T x);
      void rngstep(T mix, T& a, T& b, T*& mm, T*& m, T*& m2, T*& r, T& x, T& y);
      virtual void shuffle(T& a, T& b, T& c, T& d, T& e, T& f, T& g, T& h);
   
   private:
   
      randctx m_rc;   
   };


template<int ALPHA, class T>
   QTIsaac<ALPHA,T>:TIsaac(T a, T b, T c)
   {
      srand(a, b, c);
   }


template<int ALPHA, class T>
   QTIsaac<ALPHA,T>::~QTIsaac(void)
   {
    // DO NOTHING
   }


template<int ALPHA, class T>
   void QTIsaac<ALPHA,T>::srand(T a, T b, T c, T* s)
   {
      for(int i = 0; i < N; i++)
      {
          m_rc.randrsl = s != 0 ? s : 0;
      }
   
      m_rc.randa = a;
      m_rc.randb = b;
      m_rc.randc = c;
   
      randinit(&m_rc, true);
   }


template<int ALPHA, class T>
   inline T QTIsaac<ALPHA,T>::rand(void)
   {
      return(!m_rc.randcnt-- ? (isaac(&m_rc), m_rc.randcnt=(N-1), m_rc.randrsl[m_rc.randcnt]) : m_rc.randrsl[m_rc.randcnt]);
   }


template<int ALPHA, class T>
   void QTIsaac<ALPHA,T>::randinit(randctx* ctx, bool bUseSeed)
   {
      T a,b,c,d,e,f,g,h;
   
      a = b = c = d = e = f = g = h = GOLDEN_RATIO;
   
      T* m = (ctx->randmem);
      T* r = (ctx->randrsl);
   
      if(!bUseSeed)
      {
         ctx->randa = 0;
         ctx->randb = 0;
         ctx->randc = 0;
      }
   
    // scramble it
      int i = 0;
      for(i=0; i < 4; ++i)         
      {
         shuffle(a,b,c,d,e,f,g,h);
      }
   
      if(bUseSeed)
      {
        // initialize using the contents of r[] as the seed
      
         for(i=0; i < N; i+=8)
         {
            a+=r[i  ]; b+=r[i+1]; c+=r[i+2]; d+=r[i+3];
            e+=r[i+4]; f+=r[i+5]; g+=r[i+6]; h+=r[i+7];
         
            shuffle(a,b,c,d,e,f,g,h);
         
            m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
            m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
         }           
      
        //do a second pass to make all of the seed affect all of m
      
         for(i=0; i < N; i += 8)
         {
            a+=m[i  ]; b+=m[i+1]; c+=m[i+2]; d+=m[i+3];
            e+=m[i+4]; f+=m[i+5]; g+=m[i+6]; h+=m[i+7];
         
            shuffle(a,b,c,d,e,f,g,h);
         
            m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
            m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
         }
      }
      else
      {
        // fill in mm[] with messy stuff
      
         shuffle(a,b,c,d,e,f,g,h);
      
         m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
         m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
      }
   
      isaac(ctx);         // fill in the first set of results
      ctx->randcnt = N;   // prepare to use the first set of results
   }


template<int ALPHA, class T>
   inline T QTIsaac<ALPHA,T>::ind(T* mm, T x)
   {
    #ifndef __ISAAC64
      return (*(T*)((byte*)(mm) + ((x) & ((N-1)<<2))));
    #else   // __ISAAC64
    return (*(T*)((byte*)(mm) + ((x) & ((N-1)<<3))));
    #endif  // __ISAAC64
   }


template<int ALPHA, class T>
   inline void QTIsaac<ALPHA,T>::rngstep(T mix, T& a, T& b, T*& mm, T*& m, T*& m2, T*& r, T& x, T& y)
   {
      x = *m;  
      a = (a^(mix)) + *(m2++);
      *(m++) = y = ind(mm,x) + a + b;
      *(r++) = b = ind(mm,y>>ALPHA) + x;
   }


template<int ALPHA, class T>
   void QTIsaac<ALPHA,T>::shuffle(T& a, T& b, T& c, T& d, T& e, T& f, T& g, T& h)
   {
    #ifndef __ISAAC64
      a^=b<<11; d+=a; b+=c;
      b^=c>>2;  e+=b; c+=d;
      c^=d<<8;  f+=c; d+=e;
      d^=e>>16; g+=d; e+=f;
      e^=f<<10; h+=e; f+=g;
      f^=g>>4;  a+=f; g+=h;
      g^=h<<8;  b+=g; h+=a;
      h^=a>>9;  c+=h; a+=b;
    #else // __ISAAC64
    a-=e; f^=h>>9;  h+=a;
    b-=f; g^=a<<9;  a+=b;
    c-=g; h^=b>>23; b+=c;
    d-=h; a^=c<<15; c+=d;
    e-=a; b^=d>>14; d+=e;
    f-=b; c^=e<<20; e+=f;
    g-=c; d^=f>>17; f+=g;
    h-=d; e^=g<<14; g+=h;
    #endif // __ISAAC64
   }


template<int ALPHA, class T>
   void QTIsaac<ALPHA,T>::isaac(randctx* ctx)
   {
      T x,y;
   
      T* mm = ctx->randmem;
      T* r  = ctx->randrsl;
   
      T a = (ctx->randa);
      T b = (ctx->randb + (++ctx->randc));
   
      T* m    = mm;
      T* m2   = (m+(N/2));
      T* mend = m2;
   
      for(; m<mend; )
      {
        #ifndef __ISAAC64
         rngstep((a<<13), a, b, mm, m, m2, r, x, y);
         rngstep((a>>6) , a, b, mm, m, m2, r, x, y);
         rngstep((a<<2) , a, b, mm, m, m2, r, x, y);
         rngstep((a>>16), a, b, mm, m, m2, r, x, y);
        #else   // __ISAAC64
        rngstep(~(a^(a<<21)), a, b, mm, m, m2, r, x, y);
        rngstep(  a^(a>>5)  , a, b, mm, m, m2, r, x, y);
        rngstep(  a^(a<<12) , a, b, mm, m, m2, r, x, y);
        rngstep(  a^(a>>33) , a, b, mm, m, m2, r, x, y);
        #endif  // __ISAAC64
      }
   
      m2 = mm;
   
      for(; m2<mend; )
      {
        #ifndef __ISAAC64
         rngstep((a<<13), a, b, mm, m, m2, r, x, y);
         rngstep((a>>6) , a, b, mm, m, m2, r, x, y);
         rngstep((a<<2) , a, b, mm, m, m2, r, x, y);
         rngstep((a>>16), a, b, mm, m, m2, r, x, y);
        #else   // __ISAAC64
        rngstep(~(a^(a<<21)), a, b, mm, m, m2, r, x, y);
        rngstep(  a^(a>>5)  , a, b, mm, m, m2, r, x, y);
        rngstep(  a^(a<<12) , a, b, mm, m, m2, r, x, y);
        rngstep(  a^(a>>33) , a, b, mm, m, m2, r, x, y);
        #endif  // __ISAAC64
      }
   
      ctx->randb = b;
      ctx->randa = a;
   }


#endif // __ISAAC_HPP

1

主题

79

帖子

97

积分

注册会员

Rank: 2

积分
97
发表于 2004-5-31 11:06:00 | 显示全部楼层

Re:我写的一个随机数函数,非常容易理解,有毛病大家PP

写一个好的随机数很难, 在游戏中的随机数是有一些特殊要求的,
要满足随机的要求又要考虑执行效率,楼上的前面两位的都是和时间相关不可取。
最后一个吗执行效率应该是不怎好的,也不可取。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-7-1 12:28

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表