如何获取 rand() (C++) 的源代码
How can I get the sourcecode for rand() (C++)?
我是编程新手。
我想知道 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.c
和 random.c
。
不同的实现(如 uClibc(可能更容易阅读。在libc/stdlib文件夹下试试这里。
错了,请纠正我,但是尽管这个答案指向了部分实现,但我发现rand()
stdlib
中使用了更多内容,这是来自[glibc][2]
。从这里获得的 2.32 版本中,stdlib
文件夹包含一个random.c
文件,该文件解释了使用简单的线性全余算法。该文件夹还具有rand.c
和rand_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( 长得多这个公式。 */
- 在Linux中哪里可以找到互斥、未来等的源代码
- 如果编译的源代码是特定于它编译的硬件的,我们如何分发它
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 难以理解某些人解决IOI问题的源代码
- 使用g++编译hdf5源代码
- 如何使用C++读取另一个程序中的源代码输出
- Poco FindMySql.cmake 无法找到 MySQL 源代码
- 更改命令行 qt5 源代码构建配置的正确/快速方法
- C++出现控制台错误.我无法识别源代码的问题
- Qt Quick,如何更改 Ui 源代码?
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- 从macOS Catalina上的源代码编译LLVM(如何解决未找到"stdio.h")
- 如何使用QT创建器获取网页源代码?
- 从源代码构建 gRPC C++
- 如何使用我构建的库,而不会从源代码出错,但不为我自己的项目编译?
- 如何在使用 LLVM 编译时获取部分源代码的二进制代码
- 如何在源代码中包含外部库的头文件?
- 如何查找 torch.bmm 的 c++ 源代码 pytorch.
- 是否有可能使用debug_info获取ELF文件的源代码?
- 为什么Qt必须从源代码构建以进行交叉编译?