QT6 源(34):随机数生成器类 QRandomGenerator 的源码阅读

(1)代码来自 qrandom.h ,结合官方的注释

#ifndef QRANDOM_H
#define QRANDOM_H#include <QtCore/qalgorithms.h>
#include <algorithm>    // for std::generate
#include <random>       // for std::mt19937#ifdef min
#  undef min
#endif
#ifdef max
#  undef max
#endifQT_BEGIN_NAMESPACE  //说明本类直接定义在 QT 的命名空间class QRandomGenerator //Note: All functions in this class are reentrant.
{// restrict the template parameters to// unsigned integers 32 bits wide or larger// 为 true 时要求模板参数 UINT 在 32bit 以上template <typename UInt> //定义模板变量,本值是布尔量using IfValidUInt = typename std::enable_if<std::is_unsigned<UInt>::value &&sizeof(UInt) >= sizeof(uint), bool>::type;private: //私有部分会包含重要的数据成员的定义//typedef  QIntegerForSizeof<void *>::Signed  qptrdiff;Q_CORE_EXPORT quint64 _fillRange(void *buffer, qptrdiff count);//应该是从 buffer 地址开始填充 count 个随机数struct InitialRandomData { //本类用作下面的友元函数的返回值类型//typedef QIntegerForSizeof<void *>::Unsigned quintptr;quintptr data[16 / sizeof(quintptr)]; //sizeof(quintptr) = 8};friend InitialRandomData qt_initial_random_value() noexcept; //友元函数friend class QRandomGenerator64 ; //友元类struct SystemGenerator          ; //类声明struct SystemAndGlobalGenerators;using RandomEngine = std::mersenne_twister_engine< //模板别名quint32, 32,624,397,31,0x9908b0df,11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253>;union Storage //定义了类中类{uint dummy ;           //本类的数据成员
#ifdef Q_COMPILER_UNRESTRICTED_UNIONS //if分支有效RandomEngine twister;  //本类的成员变量RandomEngine & engine()       { return twister; }const RandomEngine & engine() const { return twister; }
#else                                 //else分支作废std::aligned_storage<sizeof(RandomEngine), alignof(RandomEngine)>::type buffer;RandomEngine &engine() { return reinterpret_cast<RandomEngine &>(buffer); }const RandomEngine &engine() const { return reinterpret_cast<const RandomEngine &>(buffer); }
#endifstatic_assert(std::is_trivially_destructible<RandomEngine>::value,"std::mersenne_twister not trivially平凡地 destructible as expected");constexpr Storage(); //本类的默认构造函数};Storage storage; //本随机类的数据成员uint    type   ; //又一个数据成员public://Initializes this QRandomGenerator object with the value seedValue//as the seed. Two objects constructed or reseeded with the same seed value//will produce the same number sequence.QRandomGenerator(quint32 seedValue = 1)  //本类的有参构造函数: QRandomGenerator(&seedValue, 1) {} //带默认参数,也可以作为无参构造函数//Initializes this QRandomGenerator object//with the values found in the array seedBuffer as the seed.//Two objects constructed or reseeded with the same seed value//will produce the same number sequence.//可以这么用: uint t[3]={1,2,3};  //此处必须是无符号数组, int 数组会报错//      QRandomGenerator ma(t);template <qsizetype N> //普通类型的模板参数,必须给值的QRandomGenerator(const quint32 (&seedBuffer)[N]) //形参是整型数组: QRandomGenerator(seedBuffer, seedBuffer + N) {}//Initializes this QRandomGenerator object//with len values found in the array seedBuffer as the seed.QRandomGenerator(const quint32 * seedBuffer, qsizetype len): QRandomGenerator(seedBuffer, seedBuffer + len) {}Q_CORE_EXPORT QRandomGenerator(std::seed_seq & sseq) noexcept;//构造函数//Initializes this QRandomGenerator object//with the values found in the range from begin to end as the seed.Q_CORE_EXPORT QRandomGenerator(const quint32 *begin, const quint32 *end);//本类的静态成员函数,返回一个指针,指向随机数生成器对象。英文注释讲解略//返回一个指向共享ORandomGenerator的指针,//该共享ORandomGenerator总是使用操作系统提供的工具来生成随机数。//系统设施在至少以下操作系统上被认为是加密安全的:苹果操作系统(Darwin)、BSD、//Linux、Windows。在其他操作系统上也可能出现这种情况。//他们也可能支持一个真正的硬件随机数发生器。//因此,此函数返回的ORandomGenerator不应用于批量数据生成。//相反,可以用它从<random>头部种子化ORandomGenerator或一个随机引擎。//此函数返回的对象是线程安全的,可以在任何线程中使用,无需锁定。//它也可以被复制,生成的 ORandomGenerator也会访问操作系统设施,但它们不会生成相同的序列。static inline Q_DECL_CONST_FUNCTION QRandomGenerator * system();//老师说不要用这个函数大量生成随机数据,只用来生成种子即可。!!!!++++//返回一个共享的QRandomGenerator的指针,该指针使用securelySeeded()进行初始化。//此函数应用于创建随机数据,//而无需为特定用途创建昂贵的securely-seeded ORandomGenerator//或存储较大的 QRandomGenerator对象。//对这个对象的访问是线程安全的,因此可以在任何线程中使用,无需锁定。//该对象也可以被复制,而复制产生的序列将与共享对象产生的序列相同。//但是,请注意,如果有其他线程访问全局对象,这些线程可能会在不可预测的间隔内获取样本。static inline Q_DECL_CONST_FUNCTION QRandomGenerator * global();//返回指针//老师说,一般情况用这个静态函数就足够了。!!!!!++++++//返回一个新的 QRandomGenerator 对象,该对象通过 QRandomGenerator:system()//安全地进行了初始化。此函数将为 ORandomGenerator 使用的算法获取理想的种子大小,//因此是创建将保留-段时间的新 ORandomGenerator 对象的推荐方法。//考虑到安全启动确定性引擎所需的数据量,这个函数有些昂贵,//不应用于QRandomGenerator 的短期使用//(使用它生成少于 2600 字节的随机数据实际上是一种资源浪费)。//如果使用不需要那么多数据,可以考虑使用 ORandomGenerator::global()//而不是存储一个 ORandomGenerator 对象。static inline QRandomGenerator securelySeeded();  //返回生成器对象// copy constructor & assignment operator (move unnecessary)Q_CORE_EXPORT QRandomGenerator(const QRandomGenerator &other);//copy 构造函数与 copy 赋值运算符函数Q_CORE_EXPORT QRandomGenerator & operator=(const QRandomGenerator & other);friend Q_CORE_EXPORT bool //声明了全局友元函数operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2);friend bool operator!=(const QRandomGenerator &rng1,const QRandomGenerator &rng2  ){return !(rng1 == rng2);}//Generates a 32-bit random quantity数量 and returns it.//调用了本类的私有成员函数 _fillRange()以实现本函的功能quint32 generate() { return quint32(_fillRange(nullptr, 1));  }//Generates a 64-bit random quantity and returns it.quint64 generate64(){return _fillRange(nullptr, sizeof(quint64) / sizeof(quint32));}//Generates one random qreal in the canonical range [0, 1)//(that is, inclusive of zero and exclusive of 1).double generateDouble(){// IEEE 754 double precision has: 双精度数值,共 64 bit 8字节//   1 bit      sign//  10 bits     exponent  指数部分//  53 bits     mantissa  有效数字// In order for our result to be normalized in the range [0, 1), we// need exactly 53 bits of random data. Use generate64() to get enough.quint64     x = generate64();quint64 limit = Q_UINT64_C(1) << std::numeric_limits<double>::digits;x >>= std::numeric_limits<quint64>::digits - //这是个减法运算std::numeric_limits<double> ::digits ;return double(x) / double(limit);}//Generates 32-bit quantities and stores them//in the range between begin and end.// API like std::seed_seqtemplate <typename ForwardIterator>void generate(ForwardIterator begin, ForwardIterator end){std::generate(begin, end, [this]() { return generate(); });}void generate(quint32 *begin, quint32 *end){_fillRange(begin, end - begin);}//generate 与 bound 差不多,前者的取值不受限制,后者有突出边界上限的意思。//Generates one random double in the range between 0 (inclusive) and//highest (exclusive).//This function is equivalent to and is implemented as://     return generateDouble() * highest; 此行是本函数的实现原理//If the highest parameter is negative,//the result will be negative too;//if it is infinite or NaN,//the result will be infinite or NaN too (that is, not random).double bounded(double highest) //形参是 double 类型{return generateDouble() * highest;}//typedef unsigned int quint32;quint32 bounded(quint32 highest) //形参是 32 位无符号整数{quint64 value = generate();value *= highest;            //先乘法后除法才不会损失精度value /= (max)() + quint64(1);return quint32(value);}//Generates one random 32-bit quantity in the range between 0 (inclusive)//and highest (exclusive). highest must be positive.int bounded(int highest)    //函数重载{Q_ASSERT(highest > 0);return int(bounded(0U, quint32(highest)));}qint64 bounded(qint64  highest) //形参的无符号与有符号版本{Q_ASSERT(highest > 0);return qint64(bounded(quint64(0), quint64(highest)));}quint64 bounded(quint64 highest);//Generates one random 32-bit quantity in the range between//lowest (inclusive) and highest (exclusive).//The highest parameter must be greater than lowest.quint32 bounded(quint32 lowest, quint32 highest){Q_ASSERT(highest > lowest);return bounded(highest - lowest) + lowest;}int bounded(int lowest, int highest){return bounded(highest - lowest) + lowest;}quint64 bounded(quint64 lowest, quint64 highest){Q_ASSERT(highest > lowest);return bounded(highest - lowest) + lowest;}qint64 bounded(qint64 lowest, qint64 highest){return bounded(highest - lowest) + lowest;}// these functions here only to help with ambiguous overloadsqint64 bounded(int lowest, qint64 highest){return bounded(qint64(lowest), qint64(highest));}qint64 bounded(qint64 lowest, int highest){return bounded(qint64(lowest), qint64(highest));}quint64 bounded(unsigned lowest, quint64 highest){return bounded(quint64(lowest), quint64(highest));}quint64 bounded(quint64 lowest, unsigned highest){return bounded(quint64(lowest), quint64(highest));}//Generates count 32- or 64-bit quantities (depending on the type UInt)//and stores them in the buffer pointed by buffer.//This is the most efficient way to obtain more than one quantity at a time,//as it reduces the number of calls into the Random Number Generator source.template <typename UInt, IfValidUInt<UInt> = true>void fillRange(UInt * buffer, qsizetype count){_fillRange(buffer, count * sizeof(UInt) / sizeof(quint32));}//Generates N 32- or 64-bit quantities (depending on the type UInt)//and stores them in the buffer array.template <typename UInt, size_t N, IfValidUInt<UInt> = true>void fillRange(UInt (&buffer)[N]) //形参是数组名的类型,N由模板参数确定了{_fillRange(buffer, N * sizeof(UInt) / sizeof(quint32));}// API like std:: random enginestypedef quint32 result_type; //重载了括号 () 运算符,使本类成为了可调用对象result_type operator()() { return generate(); }//Reseeds this object using the value seed as the seed.void seed(quint32 s = 1) { *this = { s }; }void seed(std::seed_seq & sseq) noexcept { *this = { sseq }; }//Discards the next z entries from the sequence.//This method is equivalent to calling generate() z times//and discarding the result, 形参是丢掉 z 个随机数Q_CORE_EXPORT void discard(unsigned long long z);//Returns the minimum value that QRandomGenerator may ever generate.//That is, 0.static constexpr result_type min(){ return std::numeric_limits<result_type>::min(); }//Returns the maximum value that QRandomGenerator may ever generate.//That is, std::numeric_limits<result_type>::max().static constexpr result_type max(){ return std::numeric_limits<result_type>::max(); }protected:enum System {}; //本类的 protected 属性的成员函数QRandomGenerator(System); //这是一个构造函数};class QRandomGenerator64 : public QRandomGenerator //子类的 64 bit 生成器
{QRandomGenerator64(System);
public:// unshadow generate() overloads, since we'll override.using QRandomGenerator::generate;quint64 generate() { return generate64(); }typedef quint64 result_type;result_type operator()() { return generate64(); }#ifndef Q_QDOCQRandomGenerator64(quint32 seedValue = 1): QRandomGenerator(seedValue) {}template <qsizetype N>QRandomGenerator64(const quint32 (&seedBuffer)[N]): QRandomGenerator(seedBuffer) {}QRandomGenerator64(const quint32 *seedBuffer, qsizetype len): QRandomGenerator(seedBuffer, len) {}QRandomGenerator64(std::seed_seq &sseq) noexcept: QRandomGenerator(sseq) {}QRandomGenerator64(const quint32 *begin, const quint32 *end): QRandomGenerator(begin, end) {}QRandomGenerator64(const QRandomGenerator &other): QRandomGenerator(other) {}void discard(unsigned long long z){Q_ASSERT_X(z * 2 > z, "QRandomGenerator64::discard","Overflow. Are you sure you want to skip over 9 quintillion samples?");QRandomGenerator::discard(z * 2);}static constexpr result_type min(){ return std::numeric_limits<result_type>::min(); }static constexpr result_type max(){ return std::numeric_limits<result_type>::max(); }static Q_DECL_CONST_FUNCTION Q_CORE_EXPORT QRandomGenerator64 *system();static Q_DECL_CONST_FUNCTION Q_CORE_EXPORT QRandomGenerator64 *global();static Q_CORE_EXPORT QRandomGenerator64 securelySeeded();
#endif // Q_QDOC
};inline quint64 QRandomGenerator::bounded(quint64 highest)
{// Implement an algorithm similar to libc++'s uniform_int_distribution:// loop around getting a random number, mask off any bits that "highest"// will never need, then check if it's higher than "highest". The number of// times the loop will run is unbounded but the probability of terminating// is better than 1/2 on each iteration. Therefore, the average loop count// should be less than 2.const int width = qCountLeadingZeroBits(highest - 1);const quint64 mask = (quint64(1) << (std::numeric_limits<quint64>::digits - width)) - 1;quint64 v;do {v = generate64() & mask;} while (v >= highest);return v;
}inline QRandomGenerator * QRandomGenerator::system()
{   //本函利用系统资源生成随机数生成器return QRandomGenerator64::system();
}inline QRandomGenerator * QRandomGenerator::global()
{return QRandomGenerator64::global();
}//由这里可见,子类的 64 bit的随机数生成器更重要,更基础。QRandomGenerator QRandomGenerator::securelySeeded()
{return QRandomGenerator64::securelySeeded();
}QT_END_NAMESPACE#endif // QRANDOM_H

(2)

谢谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/77172.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第二篇:linux之Xshell使用及相关linux操作

第二篇&#xff1a;linux之Xshell使用及相关linux操作 文章目录 第二篇&#xff1a;linux之Xshell使用及相关linux操作一、Xshell使用1、Xshell安装2、Xshell使用 二、Bash Shell介绍与使用1、什么是Bash Shell(壳)&#xff1f;2、Bash Shell能干什么&#xff1f;3、平时如何使…

MCP(模型上下文协议)学习笔记

学习MCP&#xff08;模型上下文协议&#xff09;的系统化路径&#xff0c;结合技术原理、工具实践和社区资源&#xff0c;帮助你高效掌握这一AI交互标准&#xff1a; 在当今人工智能飞速发展的时代&#xff0c;AI技术正以前所未有的速度改变着我们的生活和工作方式。然而&#…

MIR-2025 | 多模态知识助力机器人导航:从复杂环境到高效路径规划

作者&#xff1a;Hui Yuan, Yan Huang, Zetao Du, Naigong Yu, Ziqi Liu, Dongbo Zhang, Kun Zhang 单位&#xff1a;北京工业大学信息科学与技术学院&#xff0c;北京工业大学计算智能与智能系统北京市重点实验室&#xff0c;中科院自动化研究所模式识别国家重点实验室与多智…

javaSE.泛型界限

现在有一个新的需求&#xff0c;没有String类型成绩了&#xff0c;但是成绩依然可能是整数&#xff0c;也可能是小数&#xff0c;这是我们不希望用户将泛型指定为除数字类型外的其他类型&#xff0c;我们就需要使用到泛型的上界定义&#xff1a; 上界&#x1f447;只能使用其本…

压缩包网页预览(zip-html-preview)

zip-html-preview 项目介绍 这是一个基于 Spring Boot 开发的在线 ZIP 文件预览工具,主要用于预览 ZIP 压缩包中的 HTML 文件及其相关资源。 主要功能 支持拖拽上传或点击选择多个 ZIP 文件自动解压并提取 ZIP 文件中的 HTML 文件在线预览 HTML 文件及其相关的 CSS、JavaSc…

QML之Overlay

Overlay&#xff08;覆盖层&#xff09;是QML中用于在当前界面之上显示临时内容的重要组件。 一、Overlay基础概念 1.1 什么是Overlay&#xff1f; Overlay是一种浮动在现有界面之上的视觉元素&#xff0c;具有以下特点&#xff1a; 临时显示&#xff0c;不影响底层布局 通…

iso17025证书申请方法?iso17025认证意义

ISO/IEC 17025证书申请方法 ISO/IEC 17025是检测和校准实验室能力的国际标准&#xff0c;申请CNAS认可的流程如下&#xff1a; 1. 前期准备 标准学习&#xff1a;深入理解ISO/IEC 17025:2017标准要求。 差距分析&#xff1a;评估现有实验室管理与技术能力与标准的差距。 制…

reverse3 1(Base加密)

题目 做法 下载安装包&#xff0c;解压&#xff0c;把解压后的文件拖进Exeinfo PE进行分析 32位&#xff0c;无壳 扔进IDA&#xff08;32位&#xff09;&#xff0c;找到main&#xff0c;F5反编译 只是因为在人群中多看了你一眼——第31行的right flag&#xff0c;关键词找到…

电控---CMSIS概览

1. CMSIS库简介 CMSIS&#xff08;Cortex Microcontroller Software Interface Standard&#xff0c;Cortex微控制器软件接口标准&#xff09;是由ARM公司开发的一套标准化软件接口&#xff0c;旨在为基于ARM Cortex-M系列处理器&#xff08;如Cortex-M0/M0/M3/M4/M7/M33等&am…

list.

列表类型是用来存储多个有序的字符串&#xff0c;列表中的每个字符串称为元素&#xff08;element&#xff09;&#xff0c;⼀个列表最多可以存储个元素 在 Redis 中&#xff0c;可以对列表两端插入&#xff08;push&#xff09;和弹出&#xff08;pop&#xff09;&#xff0c;…

关于Diamond机械手的运动学与动力学的推导

1.关于Diamond机械手 &#xff08;1&#xff09;位置模型推导 逆解&#xff1a;机械末端平台的位置与驱动关节之间的关系。 设p点在xy平面的坐标是&#xff08;x&#xff0c;y&#xff09;T&#xff0c;此时根据向量求解 OP等于向量r等于e向xy轴的向量主动臂长度向xy轴的向量…

如何新建一个空分支(不继承 master 或任何提交)

一、需求分析&#xff1a; 在 Git 中&#xff0c;我们通常通过 git branch 来新建分支&#xff0c;这些分支默认都会继承当前所在分支的提交记录。但有时候我们希望新建一个“完全干净”的分支 —— 没有任何提交&#xff0c;不继承 master 或任何已有内容&#xff0c;这该怎么…

Flask(补充内容)配置SSL 证书 实现 HTTPS 服务

没有加密的http服务&#xff0c;就像在裸泳&#xff0c;钻到水里便将你看个精光。数据在互联网上传输时&#xff0c;如果未经加密&#xff0c;随时可能被抓包软件抓住&#xff0c;里面的cookie、用户名、密码什么的&#xff0c;它会看得一清二楚&#xff0c;所以&#xff0c;只…

云服务器CVM标准型S5实例性能测评——2025腾讯云

腾讯云服务器CVM标准型S5实例具有稳定的计算性能&#xff0c;CPU采用采用 Intel Xeon Cascade Lake 或者 Intel Xeon Cooper Lake 处理器&#xff0c;主频2.5GHz&#xff0c;睿频3.1GHz&#xff0c;CPU内存配置2核2G、2核4G、4核8G、8核16G等配置&#xff0c;公网带宽可选1M、3…

什么是智算中心

智算中心是一种专门为智能计算提供强大算力支持的基础设施&#xff0c;以下是关于它的详细介绍&#xff1a; 定义与功能 智算中心是基于强大的计算能力&#xff0c;特别是针对人工智能算法进行优化的计算中心。它集成了大量的高性能计算设备&#xff0c;如 GPU 集群、FPGA 阵…

注意力机制是如何实现的

注意力机制的实现可以分解为几个核心步骤&#xff0c;其本质是通过动态计算权重&#xff0c;决定不同位置信息的重要性&#xff0c;再对信息进行加权融合。以下从数学原理、代码实现到直观解释逐步展开&#xff1a; 一、核心实现步骤 以最常见的**点积注意力&#xff08;Dot-P…

【裁员感想】

裁员感想 今天忽然感觉很emo 因为知道公司要裁员 年中百分之10 年末百分十10 我知道这个百分20会打到自己 所以还挺不开心的 我就想起 我的一个亲戚当了大学老师 我觉得真的挺好的 又有寒暑假 又不是很累 薪资也不低 又是编制 同时也觉得自己很失败 因为对自己互联网的工作又…

从信号处理角度理解图像处理的滤波函数

目录 1、预备知识 1.1 什么是LTI系统? 1.1.1 首先来看什么是线性系统,前提我们要了解什么是齐次性和叠加性。

目标检测概述

为什么基于卷积网络的目标检测模型在预测后要使用非极大值抑制 基于卷积网络的目标检测模型可能会在目标的相邻区域生成多个相互重叠框&#xff0c;每个框的预测结果都是同一个目标&#xff0c;引起同一目标的重复检测。造成这一现象的原因主要有两个&#xff0c; 基于卷积网络…

【JAVA】在idea新加artifact时,点击Build-Build Artifacts时,新加的artifact不能选中

首先保证添加artifact无问题&#xff0c;比如依赖都正确、无重复命令的情况等 办法 一 File > Invalidate Caches / Restart。 重启IDEA后&#xff0c;重新检查Artifact是否可选 办法 二 打开 Project Structure&#xff08;CtrlShiftAltS&#xff09;。 进入 Artifacts 选…