如何获取 rand() (C++) 的源代码

How can I get the sourcecode for rand() (C++)?

本文关键字:源代码 C++ rand 获取 何获取      更新时间:2023-10-16

我是编程新手。

我想知道 rand(( 到底是做什么的。

搜索仅产生有关其用法的示例。但是没有人解释函数如何生成随机数的每个步骤。他们将 rand(( 视为黑盒。

我想知道 rand(( 在做什么;每一步。

有没有资源可以让我确切地看到 rand(( 的作用?这都是开源的东西,不是吗?如果没有来源,我会接受拆卸。

我知道它返回一个随机数,但它如何生成该数字?我想看到每一步。

谢谢。

以下是当前的 glibc 实现:

/* Return a random integer between 0 and RAND_MAX.  */
int
rand (void)
{
  return (int) __random ();
}

这没有多大帮助,但__random最终打电话给__random_r

/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
   congruential bit.  Otherwise, we do our fancy trinomial stuff, which is the
   same in all the other cases due to all the global variables that have been
   set up.  The basic operation is to add the number at the rear pointer into
   the one at the front pointer.  Then both pointers are advanced to the next
   location cyclically in the table.  The value returned is the sum generated,
   reduced to 31 bits by throwing away the "least random" low bit.
   Note: The code takes advantage of the fact that both the front and
   rear pointers can't wrap on the same call by not testing the rear
   pointer if the front one has wrapped.  Returns a 31-bit random number.  */
int
__random_r (buf, result)
     struct random_data *buf;
     int32_t *result;
{
  int32_t *state;
  if (buf == NULL || result == NULL)
    goto fail;
  state = buf->state;
  if (buf->rand_type == TYPE_0)
    {
      int32_t val = state[0];
      val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
      state[0] = val;
      *result = val;
    }
  else
    {
      int32_t *fptr = buf->fptr;
      int32_t *rptr = buf->rptr;
      int32_t *end_ptr = buf->end_ptr;
      int32_t val;
      val = *fptr += *rptr;
      /* Chucking least random bit.  */
      *result = (val >> 1) & 0x7fffffff;
      ++fptr;
      if (fptr >= end_ptr)
    {
      fptr = state;
      ++rptr;
    }
      else
    {
      ++rptr;
      if (rptr >= end_ptr)
        rptr = state;
    }
      buf->fptr = fptr;
      buf->rptr = rptr;
    }
  return 0;
 fail:
  __set_errno (EINVAL);
  return -1;
}

这是10秒的谷歌搜索:

  • gcc 实现 rand((
  • rand((/srand(( 函数在 C 语言中是如何实现
  • 兰德((的实现

  • http://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a01206.html
  • http://www.gnu.org/software/libc/manual/html_node/Pseudo_002dRandom-Numbers.html

打算列出实际的搜索,但看到这显然是一个骗子,我只会投票为骗子

您可以浏览源代码以获取 C 标准的不同实现。

这个问题之前已经回答过了,你可能会在 C 的 rand(( 使用哪些常用算法找到你要找的东西?

这个答案为 glibc 的 rand(( 实现提供了代码

最简单的相当好的伪随机数生成器是线性同余生成器(LCG(。 这些是公式的迭代,例如

X_{n+1} = (a * X_n  +  c) modulo m

选择常量 a、c 和 m 来给出不可预测的序列。 X_0是随机种子值。 存在许多其他算法,但这可能足以让你继续前进。

真正好的伪随机数生成器更复杂,例如Mersenne Twister。

我想,这就是你要找的。它包含随机函数的详细解释,以及理解算法的简单C程序。

编辑:

您也应该检查这一点。可能重复。

嗯,我相信 rand 来自 C 标准库,而不是C++标准库。这两个库都没有一个实现,有几个。

你可以去像这个页面这样的地方查看glibc的源代码,glibc是大多数Linux发行版上使用的c库。对于 glibc,您可以在 stdlib 下的源文件中找到它,例如 rand.crandom.c

不同的实现(如 uClibc(可能更容易阅读。在libc/stdlib文件夹下试试这里。

如果我

错了,请纠正我,但是尽管这个答案指向了部分实现,但我发现rand() stdlib中使用了更多内容,这是来自[glibc][2]。从这里获得的 2.32 版本中,stdlib 文件夹包含一个random.c文件,该文件解释了使用简单的线性全余算法。该文件夹还具有rand.crand_r.c,可以向您显示更多源代码。 stdlib.h包含在同一个文件夹中,将显示用于宏的值,如 RAND_MAX .

/* 改进的随机数生成包。 除了标准 rand((/srand(( 类似接口,这个包还有一个特殊的状态信息接口。 初始化状态(( 例程被调用带有种子、字节数组和字节数被传入;然后初始化此数组以包含具有如此多状态的随机数生成信息信息。 状态信息量的良好大小是32、64、128 和 256 字节。 可以通过调用来切换状态具有与初始化相同的数组的 setstate(( 函数initstate((. 默认情况下,包以 128 字节的状态运行
信息并生成比线性
更好的随机数全等生成器。 如果状态信息量较少大于 32 个字节,使用简单的线性全余 RNG。在内部,状态信息被视为长整型数组;数组的第 0 个元素是正在使用的 RNG 的类型(小整数(;数组的其余部分是状态RNG的信息 因此,32 字节的状态信息将提供 7 个长篇状态信息,这将允许七次多项式。 (注:状态的第零个字
信息中还存储了一些其他信息;请参阅设置状态了解详情(。 随机数生成技术是线性的反馈移位寄存器方法,采用三项式(因为是较少的术语来总结(。 在这种方法中,最少状态表中所有数字的有效位将充当线性反馈移位寄存器,周期为 2^deg - 1(其中 deg 是正在使用的多项式的次数,假设多项式是不可约和原始的(。 高阶位将具有更长的周期,因为它们的值也是受伪随机执行低位的影响。 发电机的总周期约为度*(2度 - 1(;因此将状态信息量增加一倍对
有巨大的影响发电机的周期。 注意:度*(2 度
- 1( 是近似仅适用于大度,当移位周期注册是主导因素。 度等于 7 时,周期实际上比预测的 7*(2**7 - 1( 长得多这个公式。 */