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.pswp.cn/pingmian/77172.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/77172.shtml
英文地址,請注明出處:http://en.pswp.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 選…