为什么 rand() 的范围比 int 的范围小?
Why is the range of rand() smaller than that of int?
>我正在尝试用 5000 个随机数填充向量。每个数字都是一个整数。但我想知道为什么 rand() 只给出正整数,以及为什么它从不给出整数可以容纳的最大值。这有什么原因吗?
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int main()
{
unsigned seed = time(0);
srand(seed);
vector<int> vect(5000);
for (int i = 0; i < vect.size(); i++)
{
vect[i] = rand();
}
return 0;
}
以下是rand()
的作用:
返回介于
0
和RAND_MAX
之间的伪随机整数值(包括0
和RAND_MAX
)。
RAND_MAX
是实现定义的,但将是"至少 32767"。
除了"这就是指定的方式"之外,没有"为什么"。
如果想要一个包含一些负数的范围,则可以应用一些数学运算(例如,减法)。
请注意:
对于严重的随机数生成需求,不建议使用
rand()
。建议使用 C++11 的随机数生成工具来替换rand()
。(自C++11起)
所述设施为您提供更好的控制和更好的分配(示例)。
你没有得到完整的可能范围的原因是因为rand()
是古老的。
早在开发rand()
的日子里,实现随机数生成器的常用方法是所谓的线性全余生成器(lcg)。这不会给出非常随机的数字;事实上,如果你看过前几个,它们是可以预测的。但那时的计算机速度很慢,而且工作时间很少。
这就是为什么rand()
只承诺 15 位 - 常量RAND_MAX
定义了您可以从RAND
获得的最大值,并且可以低至32767
。 当时的 32 位计算机并不常见,因此使用 16 位数字是有意义的。对于常见的LCG实现,最低位毫无价值(在0和1之间切换),因此无论如何您都想丢弃它。
几十年的改进造就了更好的发电机。特别是,mt19937
发电机非常好,仍然非常高效。自2011年以来,C++已经<random>
,其中包括std::mt19937
。此外,为了方便起见,您现在可以选择自己的发行版,std::uniform_int_distribution<>(min,max)
如前所述rand()
已弃用,不应在实际场景中使用。但是要回答你为什么只有正整数的问题,这是因为产生负随机整数是多余的,所以你可以使用基本的数学来从产生的正随机数中产生一个负数。
举个例子:如果我想产生一个完全任意的 -5 到 27 之间的随机数,我可以只产生一个介于 0 和 32(含)之间的随机数,然后减去 5。
#include <stdio.h>
#include <stdlib.h>
int main(){
int random = (rand() % 33) - 5;
printf("%d",random);
return 0;
}
因为这不是一个实际的场景,所以我也没有随机播种。所以你不应该在你的代码中使用它,但它适用于几乎所有 RNG 函数,你只是从你的正数中减去负范围。但是,您应该使用 C++11 随机数生成器。
- 为什么在全局范围内使用"extern int a"似乎不行?
- 如何计算数据类型的范围,例如int
- 在这个无限循环中,当输入 0 时终止,当输入 int 范围之外的任何内容时,程序行为不正常
- 超出 int 的值范围后的无限循环
- "1L << count"是什么意思?如何使用超出"unsigned long long int? "范围的语句编号打印?
- 为什么 rand() 的范围比 int 的范围小?
- 从'::size_t'转换为'int'需要缩小转换范围
- std::vector<std::vector<int>>:调试断言失败。C++矢量下标超出范围保留内存
- C++. 面试. 关于返回 int* 值问题的范围
- 为什么所有可能的整数都"true"在 C++ 的 if 语句内的 long int 范围内,而 0 不是?
- 如何在给定范围内找到 std::set<pair<int、int> > 中的最大值?
- 当偏移太大(大于签名的INT 2^32范围)时,GZSEEK(ZLIB)失败
- 从'double'转换为'int'需要缩小转换范围
- 以下程序中最大 int 1000 000(在 int 范围内)的整数溢出
- 如何编写一个 boost::spirit::qi 解析器来解析从 0 到 std::numeric_limits:<int>:max() 的整数范围?
- C 使用单个生成器从多个范围内提升随机INT
- char *argv []和int argc c 的全局覆盖范围
- C++int出现次数,范围未知
- 从幻数到int或long的重载分辨率(范围为v3)
- 将 std::vector<int> 设置为一个范围