当前位置: 首页 > news >正文

程序生成随机数

随机数

  • 1. Qt
    • 1.1 qsrand() 和qrand()
    • 1.2 QRandomGenerator 类
  • 2. C语言
    • 2.1 使用 rand() 和 srand() 函数
    • 2.2 使用 <random.h> 库(C11 标准)
  • 3. C++
    • 3.1 使用 <cstdlib> 和 <ctime> 库(旧方法)
    • 3.2 使用 <random> 库(C++11 及以后推荐方法)
    • 3.3 生成浮点数随机数

1. Qt

1.1 qsrand() 和qrand()

通过qsrand() 和qrand()函数来生成随机数。随机数生成器本质上是按照特定算法生成一系列看似随机的数字。但实际上,这些数字是基于一个初始值(即种子)按照固定算法计算得出的。如果每次使用相同的种子,那么随机数生成器将产生相同的随机数序列。qsrand() 函数的作用就是为随机数生成器设置这个初始种子,从而影响后续生成的随机数序列。

  1. qsrand() 是 Qt 框架提供的一个用于初始化随机数生成器种子的函数,它在<QtCore/QRandomGenerator> (旧版本中是 <QtCore/QTime> 配合使用)相关的随机数生成操作中扮演着重要角色。
    该函数在 <QtCore/QRandomGenerator> 头文件(在旧版本中为 <QtCore/QCoreApplication> )中声明。这里的参数 seed 是一个无符号整数,作为随机数生成器的种子。
void qsrand(uint seed);
  1. qrand() 函数用于生成具体的随机数。qrand() 函数用于生成伪随机整数。该函数生成的随机数范围是 [0, RAND_MAX],其中 RAND_MAX 是一个常量,表示随机数的最大值。RAND_MAX 的值在不同的系统和编译器中可能会有所不同,但在大多数系统中,RAND_MAX 被定义为 32767 (即 2^15 - 1)。这意味着 qrand() 函数生成的随机数是一个非负整数,其取值范围从 0 到 RAND_MAX。
#include <QCoreApplication>
#include <QDebug>
#include <QTime>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 使用当前时间作为种子初始化随机数生成器qsrand(QTime::currentTime().msec());// 生成并输出10个随机整数for (int i = 0; i < 10; ++i) {int randomNumber = qrand();qDebug() << "生成的随机数: " << randomNumber;}return a.exec();
}

在这个例子中,使用 QTime::currentTime().msec() 作为种子,因为每毫秒的时间值通常是不同的,所以每次运行程序时,随机数生成器的种子不同,进而产生不同的随机数序列。qrand() 函数用于生成具体的随机数。

1.2 QRandomGenerator 类

不过,在现代 Qt(Qt 5.10 及以后版本)中,推荐使用 QRandomGenerator 类来生成随机数,它提供了更安全、更现代的随机数生成方式,而 qsrand() 和 qrand() 已被标记为过时。示例如下:

#include <QCoreApplication>
#include <QDebug>
#include <QRandomGenerator>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 生成并输出10个随机整数for (int i = 0; i < 10; ++i) {quint32 randomNumber = QRandomGenerator::global()->generate();qDebug() << "生成的随机数: " << randomNumber;}return a.exec();
}

在这个示例中,QRandomGenerator::global()->generate() 用于生成一个无符号 32 位整数的随机数,并且不需要手动设置种子,QRandomGenerator 会自动处理种子的初始化,提供更好的随机性和安全性。
QRandomGenerator::global()->bounded(0, 101) 用于生成一个范围在 [0, 100] 的随机整数

  • 可重复性问题:如果需要复现相同的随机数序列,可使用固定的种子调用 qsrand()。但在大多数实际应用场景中,为了得到不同的随机数序列,通常会使用变化的值(如当前时间)作为种子。
  • 过时性:由于 qsrand() 和 qrand() 存在一些随机性和安全性方面的问题,在新的 Qt 项目中建议使用 QRandomGenerator 类来替代。

2. C语言

2.1 使用 rand() 和 srand() 函数

  1. rand() 函数:该函数会返回一个介于 0 到 RAND_MAX 之间的伪随机整数。RAND_MAX 是一个常量,其值至少为 32767,不同系统可能会有所不同。
  2. srand() 函数:此函数用于初始化随机数生成器的种子。若每次运行程序时种子相同,rand() 函数就会生成相同的随机数序列。所以,通常会使用当前时间作为种子,以确保每次运行程序时生成不同的随机数序列。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>int main() {// 使用当前时间作为随机数生成器的种子srand(time(NULL));// 生成10个随机数for (int i = 0; i < 10; i++) {// 生成一个0到99之间的随机数int random_num = rand() % 100;printf("随机数 %d: %d\n", i + 1, random_num);}return 0;
}
  • srand(time(NULL)):time(NULL) 会返回当前的时间戳,将其作为 srand() 函数的参数,以此初始化随机数生成器的种子。
  • rand() % 100:rand() 函数生成一个随机整数,通过取模运算 % 100 可以将随机数的范围限制在 0 到 99 之间。

2.2 使用 <random.h> 库(C11 标准)

C11 标准引入了 <random.h> 库,该库提供了更强大、更灵活的随机数生成功能,能够生成不同分布的随机数,如均匀分布、正态分布等。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <random>int main() {// 创建一个随机数生成器struct random_data rd;char state[32];initstate_r(time(NULL), state, sizeof(state), &rd);// 生成10个0到99之间的随机数for (int i = 0; i < 10; i++) {int random_num;random_r(&rd, &random_num);random_num = random_num % 100;printf("随机数 %d: %d\n", i + 1, random_num);}return 0;
}
  • initstate_r():该函数用于初始化随机数生成器的状态,使用当前时间作为种子。
  • random_r():此函数会生成一个随机整数,同样通过取模运算将随机数的范围限制在 0 到 99 之间。
  • random_data 结构体是 <random.h> 头文件里定义的,这个头文件是 C11 标准引入的,用于实现更高级的随机数生成功能。random_data 结构体用于存储随机数生成器的内部状态信息。在使用 random_r 这类可重入的随机数生成函数时,就需要借助这个结构体来保存和管理随机数生成器的状态。之所以要有这样的结构体,是因为可重入函数要能在多线程环境下安全使用,每个线程得有自己独立的随机数生成器状态,避免不同线程之间的状态相互干扰。
  • 状态数组:char state[32]; 定义了一个字符数组 state,用于存储随机数生成器的状态信息。
  • 在多线程环境中使用 random_r 函数时,每个线程都需要有自己独立的 random_data 结构体变量,以此保证线程安全。

3. C++

3.1 使用 和 库(旧方法)

这种方法主要利用 rand() 函数生成随机数,同时使用 srand() 函数设置随机数种子。rand() 函数会返回一个介于 0 到 RAND_MAX 之间的伪随机整数,RAND_MAX 是一个常量,其值至少为 32767。为了让每次运行程序时生成不同的随机数序列,通常会使用 srand() 结合 time() 函数以当前时间作为种子。

#include <iostream>
#include <cstdlib>
#include <ctime>int main() {// 使用当前时间作为随机数种子std::srand(static_cast<unsigned int>(std::time(nullptr)));// 生成10个0到99之间的随机数for (int i = 0; i < 10; ++i) {int randomNumber = std::rand() % 100;std::cout << "随机数 " << i + 1 << ": " << randomNumber << std::endl;}return 0;
}
  • std::srand(static_cast(std::time(nullptr)));:使用当前时间作为随机数种子,确保每次运行程序时生成不同的随机数序列。
  • std::rand() % 100:生成一个 0 到 99 之间的随机数。

3.2 使用 库(C++11 及以后推荐方法)

库是 C++11 引入的,提供了更强大、更灵活且随机性更好的随机数生成功能。它包含了多种随机数引擎和分布类型,可以根据需求选择合适的引擎和分布来生成随机数。

#include <iostream>
#include <random>int main() {// 定义随机数引擎,这里使用默认的随机数引擎std::random_device rd;std::mt19937 gen(rd());// 定义分布类型,这里使用均匀分布,范围是0到99std::uniform_int_distribution<> dis(0, 99);// 生成10个随机数for (int i = 0; i < 10; ++i) {int randomNumber = dis(gen);std::cout << "随机数 " << i + 1 << ": " << randomNumber << std::endl;}return 0;
}
  • std::random_device rd;:创建一个 random_device 对象,它通常用于获取真正的随机数种子。
  • std::mt19937 gen(rd());:创建一个 mt19937 随机数引擎,并使用 random_device 生成的种子进行初始化。mt19937 是一个常用的梅森旋转算法随机数引擎,具有较好的随机性和性能。
  • std::uniform_int_distribution<> dis(0, 99);:创建一个均匀整数分布对象,指定随机数的范围为 0 到 99。
  • dis(gen):通过分布对象 dis 对随机数引擎 gen 进行采样,生成一个符合指定分布的随机数。

3.3 生成浮点数随机数

使用 库也可以方便地生成浮点数随机数,以下是一个生成 0 到 1 之间浮点数随机数的示例:

#include <iostream>
#include <random>int main() {std::random_device rd;std::mt19937 gen(rd());// 定义均匀浮点分布,范围是0到1std::uniform_real_distribution<> dis(0.0, 1.0);for (int i = 0; i < 10; ++i) {double randomNumber = dis(gen);std::cout << "随机浮点数 " << i + 1 << ": " << randomNumber << std::endl;}return 0;
}

这个示例与生成整数随机数的示例类似,只是使用了 std::uniform_real_distribution 来定义浮点数的均匀分布。

相关文章:

  • 4.22学习总结
  • Apache PDFBox
  • 常见的神经网络权重文件格式及其详细说明
  • 马拉松赛补给策略
  • P3416-图论-法1.BFS / 法2.Floyd
  • 计算机组成与体系结构:缓存(Cache)
  • 嘻游电玩三端客户端部署实战:PC + Android + iOS 环境全覆盖教程
  • UOS+N 卡 + CUDA 环境下 X86 架构 DeepSeek 基于 vLLM 部署与 Dify 平台搭建指南
  • React 单一职责原则:优化组件设计与提高可维护性
  • Docker 快速入门教程
  • 使用Java调用TensorFlow与PyTorch模型:DJL框架的应用探索
  • 智能座舱测试内容与步骤
  • React18+ 项目搭建-从初始化、技术选型到开发部署的全流程规划
  • 【机器学习-线性回归-2】理解线性回归中的连续值与离散值
  • std::vector 自定义分配器
  • 禁止ubuntu自动更新
  • 实战华为1:1方式1 to 2 VLAN映射
  • PCB材料选择需求分析实例
  • [预备知识]3. 自动求导机制
  • Nginx:支持 HTTPS
  • 新华社评论员:在推进中国式现代化的宽广舞台上绽放青春光彩
  • 金科股份:因信披违规,公司及董事长、总裁、财务负责人等收到行政监管措施决定书
  • “译通天下·言立寰宇”:华东师大翻译家的精神传承
  • 市场监管总局出手整治涉企乱收费,聚焦政府部门及下属单位等领域
  • 十四届全国人大常委会举行第四十四次委员长会议
  • 黄育奇当选福建惠安县人民政府县长