【问题标题】:C++ Deeper look inside rand() and srand()C++ 深入了解 rand() 和 srand()
【发布时间】:2019-09-14 08:33:26
【问题描述】:

我知道rand()srand() 是如何相互关联的,我知道我应该如何使用它们,但是它们的工作机制对我来说真的很有趣,我想知道它们是如何工作的 ?!,但我找不到任何特别的东西。

所以这是我的问题:rand()srand() 的深处发生了什么,它是如何产生随机数的? (如果它真的产生一个随机的!)它有任何特殊的数学计算或任何特殊的算法吗?这是什么?

【问题讨论】:

  • Rand 是实现定义的,尽管它通常实现为线性同余生成器。但是,可以在标准 标头中找到定义明确的生成器。并且可能更值得一看,因为众所周知 rand通常会产生低质量的随机数。
  • 如果你想知道“它们是如何工作的?!”看看你的标准库实现
  • 参见stackoverflow.com/questions/24005459/… 了解标准的内容以及大多数实现的作用。准备好大失所望。
  • @George -- 有点超技术,但rand() 的实现是特定于实现的,而不是特定于实现的。在 C 和 C++ 标准中,“定义的实现”意味着符合标准的实现必须记录它所做的事情。 rand() 不需要。

标签: c++ random random-seed


【解决方案1】:

首先,rand() 不会产生随机数字。这是一个Pseudo Random Number Generator

rand()通常实现为linear congruential generator。 你可以认为有一个变量seed,它保存了生成器之前的状态,那么rand()只是使用这个种子来生成序列中的下一个数字。

类似这样的东西(非常粗略的实现,只是为了解释这个想法):

const int RAND_MAX = 32767; // usually it is 2^15, but actually implementation specific
const int a = ...;          // implementation specific
const int c = ...;          // implementation specific
int seed = 0;               // current generator state

void srand(int _seed) {
  seed = _seed;
}

int rand() {
  int r = (a * seed + c) % RAND_MAX;
  seed = r;
  return r;
}

它将为相同的初始状态(种子值)创建相同的序列。

【讨论】:

  • "rand() 被实现为线性同余生成器",通常是正确的,但这不是标准要求。
  • Off-by-one 错误 -- RAND_MAX 是可以生成的最大值,所以余数应该是 RAND_MAX + 1。另外,我认为“通常是 2^15”被夸大了。它必须至少为 2^15,但最简单的实现是直接使用硬件,这会丢弃溢出位,即,对于 32 位寄存器,RAND_MAX 最自然是 2^31。 +1。
猜你喜欢
  • 2020-12-12
  • 2014-05-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多