【问题标题】:Rand Implementation兰德实施
【发布时间】:2011-06-13 16:22:06
【问题描述】:

我想了解如何实现 rand() 和 srand() 函数,并想调整代码以根据我的要求进行修改。我在哪里可以找到 rand() 和 srand() 的源代码。

【问题讨论】:

    标签: c gcc random


    【解决方案1】:

    randsrand 通常实现为一个简单的LCG,您可以轻松编写自己的代码(几行代码),而无需查找randsrand 的来源。请注意,如果您出于“严肃”目的(例如密码学)需要随机数,则 RNG 比 LCG 好得多。

    顺便说一句,C 标准本身包括randsrand 的示例实现:

    static unsigned long int next = 1;
    
    int rand(void) // RAND_MAX assumed to be 32767
    {
        next = next * 1103515245 + 12345;
        return (unsigned int)(next/65536) % 32768;
    }
    
    void srand(unsigned int seed)
    {
        next = seed;
    }
    

    【讨论】:

      【解决方案2】:

      它需要一个种子作为输入参数,通常如下:-

      double result = srand(time(NULL));
      

      并返回一个随机数,该随机数符合概率和预期的出现次数。

      来自CodeGuru forums:-

      void __cdecl srand (unsigned int seed)
      {
          #ifdef _MT
              _getptd()->_holdrand = (unsigned long)seed;
          #else /* _MT */
              holdrand = (long)seed;
          #endif /* _MT */
      }
      
      int __cdecl rand (void)
      {
         #ifdef _MT
          _ptiddata ptd = _getptd();
          return( ((ptd->_holdrand = ptd->_holdrand * 214013L + 2531011L) >> 16) &
          0x7fff );
         #else /* _MT */
          return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
         #endif /* _MT */
      }
      

      希望这会有所帮助。

      【讨论】:

      • 根据这段代码holdrand 会快速增长并很快导致溢出。 holdrand = holdrand * 214013L + 2531011L
      • 关于double result = srand(time(NULL));:你到底为什么有那个double resultsrand 没有返回值...
      • 你能提供代码的小解释或指出确切的代码
      • @nikhil:_MT 是处理多线程的代码(多线程运行时库为每个线程保留单独的 RNG 状态);请注意,这就是我避免发布实际库代码的原因:它通常包含与实际问题无关的“干扰元素”。
      • @nightcracker:确定它会溢出,但这没关系,因为这是一个仅用于支持它的系统的实现。将标准库(编译器或操作系统作者)放在一起的人不应该在有符号整数溢出导致硬件异常的系统上使用它......
      【解决方案3】:

      glibc (由 gcc 使用)是一个简单的公式:

      x = 1103515245 * x + 12345
      

      在 232 处环绕,如 here 所示。您可以将 x 设置为种子,然后继续调用函数来评估该表达式(并更新种子)。

      但您应该知道,像这样的线性同余生成器被认为是足够的,但并不理想。

      虽然唯一理想的随机数生成器是完全随机的,但Mersenne Twister 可能更接近。

      【讨论】:

      • s/足够/平庸/,我会说。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 1970-01-01
      • 2018-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多