188188
189189 < p class ="text-right "> < small >
190190 最終更新日時(UTC):
191- < span itemprop ="datePublished " content ="2025-10-22T16:15:43 ">
192- 2025年10月22日 16時15分43秒
191+ < span itemprop ="datePublished " content ="2026-03-19T02:23:48 ">
192+ 2026年03月19日 02時23分48秒
193193 </ span >
194194 < br />
195195 < span itemprop ="author " itemscope itemtype ="http://schema.org/Person ">
215215 < div class ="identifier-type "> function template</ div > < div class ="header "> <random></ div > < h1 itemprop ="name "> < span class ="namespace " title ="namespace std "> std::</ span > < span class ="token "> generate_canonical</ span > < span class ="cpp cpp11 " title ="C++11で追加 "> (C++11)</ span > </ h1 >
216216< div itemprop ="articleBody "> < p > < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="k "> namespace</ span > < span class ="w "> </ span > < span class ="nn "> std</ span > < span class ="w "> </ span > < span class ="p "> {</ span >
217217< span class ="w "> </ span > < span class ="k "> template</ span > < span class ="o "> <</ span > < span class ="k "> class</ span > < span class ="w "> </ span > < span class ="nc "> RealType</ span > < span class ="p "> ,</ span > < span class ="w "> </ span > < span class ="n "> < a href ="../cstddef/size_t.html "> std::size_t</ a > </ span > < span class ="w "> </ span > < span class ="n "> bits</ span > < span class ="p "> ,</ span > < span class ="w "> </ span > < span class ="k "> class</ span > < span class ="w "> </ span > < span class ="nc "> URBG</ span > < span class ="o "> ></ span >
218- < span class ="w "> </ span > < span class ="n "> RealType</ span > < span class ="w "> </ span > < span class ="n "> generate_canonical</ span > < span class ="p "> (</ span > < span class ="n "> URBG</ span > < span class ="o "> &</ span > < span class ="w "> </ span > < span class ="n "> g</ span > < span class ="p "> );</ span >
218+ < span class ="w "> </ span > < span class ="n "> RealType</ span > < span class ="w "> </ span > < span class ="n "> generate_canonical</ span > < span class ="p "> (</ span > < span class ="n "> URBG</ span > < span class ="o "> &</ span > < span class ="w "> </ span > < span class ="n "> g</ span > < span class ="p "> );</ span > < span class ="w "> </ span > < span class ="c1 "> // (1) C++11</ span >
219+
220+ < span class ="w "> </ span > < span class ="k "> template</ span > < span class ="o "> <</ span > < span class ="k "> class</ span > < span class ="w "> </ span > < span class ="nc "> RealType</ span > < span class ="p "> ,</ span > < span class ="w "> </ span > < span class ="n "> < a href ="../cstddef/size_t.html "> std::size_t</ a > </ span > < span class ="w "> </ span > < span class ="n "> digits</ span > < span class ="p "> ,</ span > < span class ="w "> </ span > < span class ="k "> class</ span > < span class ="w "> </ span > < span class ="nc "> URBG</ span > < span class ="o "> ></ span >
221+ < span class ="w "> </ span > < span class ="n "> RealType</ span > < span class ="w "> </ span > < span class ="n "> generate_canonical</ span > < span class ="p "> (</ span > < span class ="n "> URBG</ span > < span class ="o "> &</ span > < span class ="w "> </ span > < span class ="n "> g</ span > < span class ="p "> );</ span > < span class ="w "> </ span > < span class ="c1 "> // (1) C++26</ span >
219222< span class ="p "> }</ span >
220223</ code > </ pre > </ div >
221224</ p >
@@ -225,15 +228,55 @@ <h2>概要</h2>
225228< h2 > テンプレートパラメータ</ h2 >
226229< ul >
227230< li > < code > class RealType</ code > : 生成する実数の型。</ li >
228- < li > < code > size_t bits</ code > : 生成する実数における仮数部への分解能の最低要求。最大値は < code > std::< a href ="../limits/numeric_limits.html "> numeric_limits</ a > <RealType>::< a href ="../limits/numeric_limits/digits.html "> digits</ a > </ code > 。</ li >
231+ < li > < code > size_t bits</ code > : 生成する実数における仮数部への分解能の最低要求。最大値は < code > std::< a href ="../limits/numeric_limits.html "> numeric_limits</ a > <RealType>::< a href ="../limits/numeric_limits/digits.html "> digits</ a > </ code > < ul >
232+ < li > C++26で< code > digits</ code > に名称変更</ li >
233+ </ ul >
234+ </ li >
235+ < li > < code > size_t digits</ code > : 生成する実数における基数非依存の桁数としての分解能の最低要求。最大値は < code > std::< a href ="../limits/numeric_limits.html "> numeric_limits</ a > <RealType>::< a href ="../limits/numeric_limits/digits.html "> digits</ a > </ code > 。</ li >
229236< li > < code > class URBG</ code > : 一様乱数生成器の型。</ li >
230237</ ul >
231238< h2 > 関数パラメータ</ h2 >
232239< ul >
233240< li > URBG& g : 一様乱数生成器。</ li >
234241</ ul >
242+ < h2 > 効果</ h2 >
243+ < ul >
244+ < li >
245+ < p > C++11からC++23まで :
246+ 以下の変数を定義する。</ p >
247+ < ul >
248+ < li > < code > R</ code > = < code > g.< a href ="uniform_random_bit_generator.html "> max()</ a > - g.< a href ="uniform_random_bit_generator.html "> min()</ a > + 1</ code > </ li >
249+ < li > < code > k</ code > = max(1, ⌈< code > bits</ code > / log< sub > 2</ sub > < code > R</ code > ⌉)</ li >
250+ < li > < code > S</ code > = < code > g()</ code > から < code > k</ code > 回呼び出した結果を < code > R</ code > のべき乗で重み付けして累積した値</ li >
251+ </ ul >
252+ < p > < a class ="cpprefjp-defined-word " data-desc ="関数呼び出し式の評価結果となるオブジェクト・値 "> 戻り値</ a > は < code > S</ code > / < code > R</ code > < sup > < code > k</ code > </ sup > となる。ただし浮動小数点数の丸めにより、結果が1.0になる場合がある。</ p >
253+ </ li >
254+ < li >
255+ < p > C++26 :
256+ 以下の変数を定義する。</ p >
257+ < ul >
258+ < li > < code > r</ code > = < code > < a href ="../limits/numeric_limits.html "> numeric_limits</ a > <RealType>::< a href ="../limits/numeric_limits/radix.html "> radix</ a > </ code > </ li >
259+ < li > < code > R</ code > = < code > g.< a href ="uniform_random_bit_generator.html "> max()</ a > - g.< a href ="uniform_random_bit_generator.html "> min()</ a > + 1</ code > </ li >
260+ < li > < code > d</ code > = min(< code > digits</ code > , < code > < a href ="../limits/numeric_limits.html "> numeric_limits</ a > <RealType>::< a href ="../limits/numeric_limits/digits.html "> digits</ a > </ code > )</ li >
261+ < li > < code > k</ code > = < code > R</ code > < sup > < code > k</ code > </ sup > ≥ < code > r</ code > < sup > < code > d</ code > </ sup > を満たす最小の整数</ li >
262+ < li > < code > x</ code > = ⌊< code > R</ code > < sup > < code > k</ code > </ sup > / < code > r</ code > < sup > < code > d</ code > </ sup > ⌋</ li >
263+ </ ul >
264+ < p > 以下の手順で乱数を生成する。</ p >
265+ < ol >
266+ < li > < code > g()</ code > を < code > k</ code > 回呼び出して値 < code > S</ code > を生成する</ li >
267+ < li > < code > S</ code > ≥ < code > x</ code > · < code > r</ code > < sup > < code > d</ code > </ sup > の場合、手順1に戻って再試行する(棄却法)</ li >
268+ < li > < a class ="cpprefjp-defined-word " data-desc ="関数呼び出し式の評価結果となるオブジェクト・値 "> 戻り値</ a > は ⌊< code > S</ code > / < code > x</ code > ⌋ / < code > r</ code > < sup > < code > d</ code > </ sup > となる</ li >
269+ </ ol >
270+ < p > この棄却法により、浮動小数点数の丸めで結果が1.0になる問題が解消され、< a class ="cpprefjp-defined-word " data-desc ="関数呼び出し式の評価結果となるオブジェクト・値 "> 戻り値</ a > は必ず0以上1未満となることが保証される。</ p >
271+ </ li >
272+ </ ul >
235273< h2 > < a class ="cpprefjp-defined-word " data-desc ="問題が発生したときに、現在実行位置を過去に通過・記録した位置に戻し、文脈情報を添えて紐づけられた処理(例外ハンドラー)を呼び出す仕組み。またはその事態 "> 例外</ a > </ h2 >
236274< p > < code > URBG g</ code > が< a class ="cpprefjp-defined-word " data-desc ="問題が発生したときに、現在実行位置を過去に通過・記録した位置に戻し、文脈情報を添えて紐づけられた処理(例外ハンドラー)を呼び出す仕組み。またはその事態 "> 例外</ a > を送出する場合はそれに準ずる。</ p >
275+ < h2 > 備考</ h2 >
276+ < ul >
277+ < li > C++23まではアルゴリズムの仕様上、浮動小数点数の丸めにより値< code > 1.0</ code > が生成されることがあった</ li >
278+ < li > C++26では棄却法(reject-and-retry)方式が導入され、< a class ="cpprefjp-defined-word " data-desc ="関数呼び出し式の評価結果となるオブジェクト・値 "> 戻り値</ a > が[0.0, 1.0)の範囲内であることが保証されるようになった</ li >
279+ </ ul >
237280< h2 > 例</ h2 >
238281< p > < div class ="yata " id ="6ad591c95fc0de21c2451287d942e53573a3fe45 "> < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="cp "> #include < a href ="../random.html "> <random></ a > </ span >
239282< span class ="cp "> #include < a href ="../iostream.html "> <iostream></ a > </ span >
@@ -283,16 +326,16 @@ <h3>備考</h3>
283326< li > GCC 4.9時点において、< code > float</ code > 型を指定した場合に、値< code > 1.0</ code > が生成されることがあるバグがある(< a href ="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63176 " target ="_blank "> Bug 63176</ a > )</ li >
284327< li > Clang 3.3時点において、値< code > 1.0</ code > が生成されることがある(< a href ="https://llvm.org/bugs/show_bug.cgi?id=18767 " target ="_blank "> Bug 18767</ a > )</ li >
285328</ ul >
286- < h3 > 参考</ h3 >
287- < ul >
288- < li > N3337 p.909 §26.5.7.2</ li >
289- </ ul >
290329< h2 > 参照</ h2 >
291330< ul >
292331< li > < a href ="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0346r1.pdf " target ="_blank "> P0346R1 A < code > <random></ code > Nomenclature Tweak</ a > < ul >
293332< li > URNGをURBGに変更</ li >
294333</ ul >
295334</ li >
335+ < li > < a href ="https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0952r2.html " target ="_blank "> P0952R2 A New Specification for < code > generate_canonical</ code > </ a > < ul >
336+ < li > C++26でテンプレートパラメータ名を< code > bits</ code > から< code > digits</ code > に変更し、棄却法による新しいアルゴリズムを導入</ li >
337+ </ ul >
338+ </ li >
296339</ ul > </ div >
297340
298341 </ div >
0 commit comments