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

C++ 如何获取rand()的源代码(C+;+;)?,c++,random,C++,Random,我是编程新手 我想知道rand()到底做什么 搜索只会产生有关其用法的示例。但没有人解释函数如何生成随机数的每一步。他们将rand()视为黑盒 我想知道兰德()在做什么;每一步 是否有一个资源可以让我确切地了解rand()的功能? 这都是开源的东西,不是吗?如果没有来源,我会接受拆卸 我知道它返回一个随机数,但它是如何生成那个数的?我想看看每一步 谢谢。您可以浏览C标准不同实现的源代码 这个问题以前已经回答过了,你可能会找到你想要的 这个答案为glibc实现rand()提供了代码。下面是: 这没

我是编程新手

我想知道rand()到底做什么

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

我想知道兰德()在做什么;每一步

是否有一个资源可以让我确切地了解rand()的功能? 这都是开源的东西,不是吗?如果没有来源,我会接受拆卸

我知道它返回一个随机数,但它是如何生成那个数的?我想看看每一步


谢谢。

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

这个问题以前已经回答过了,你可能会找到你想要的

这个答案为glibc实现rand()提供了代码。下面是:

这没有多大帮助,但
\uu random
最终会调用:


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

X_{n+1} = (a * X_n  +  c) modulo m
常数a、c和m被选择用于给定不可预测的序列。X_0是随机种子值。还有很多其他的算法,但这可能足以让你继续

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

我想,这就是您要寻找的。它包含了对随机函数的详细解释,并用简单的C程序来理解算法

编辑:


你也应该检查一下。一个可能的副本。

这是10秒的谷歌搜索:


<>我想列出实际的搜索,但是看到这个显然是一个骗局,我会投票给Dupe < /P> < p>嗯,我相信伦德是来自C标准库,而不是C++标准库。这两个库都没有一个实现,有几个实现

您可以去一些地方查看glibc的源代码,glibc是大多数Linux发行版上使用的c库。对于glibc,您可以在stdlib下的源文件中找到它,例如
rand.c
random.c


另一种实现,如uClibc,可能更容易阅读。在libc/stdlib文件夹下。

如果我错了,请纠正我,但尽管指向部分实现,但我发现在
stdlib
中使用的
rand()
还有更多内容,它来自
[glibc][2]
。根据从中获得的数据,
stdlib
文件夹包含一个
random.c
文件,该文件说明使用了简单的线性同余算法。该文件夹还有
rand.c
rand\u r.c
,可以显示更多的源代码<包含在同一文件夹中的code>stdlib.h将显示用于宏的值,如
RAND_MAX

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


你关心什么系统?可能实现的数量与环境的数量差不多。您的编译器可能有可用的运行时库源代码。rand使用伪随机生成器,因此阅读PRNG背后的理论比任何一段源代码都更具启发性,这是一部经典之作,并不难理解,它涵盖了基础知识,尽管按照现代标准来看,它是原始的。(但是,
rand()
)请解释一下-1?好的。我对编程非常陌生(~3天!),所以我不知道该搜索什么。我在这里找到了我需要研究的实现:@user2071506哦
/* 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;
}
X_{n+1} = (a * X_n  +  c) modulo m