C++ でランダム double 型を生成する方法
 
この記事では、C++ でランダムな倍精度浮動小数点数を生成する方法のいくつかの方法について説明します。
C++ で C++11 <random> ライブラリを使用してランダムな double を生成する
    
C++11 バージョン以降、標準ライブラリには、乱数/擬似乱数生成のためのクラスとメソッドが用意されています。高品質の乱数を必要とするアプリケーションではこれらのメソッドを使用しなければなりませんが、それ以外のケースでも、このクリーンで機能豊富な STL インターフェースの恩恵を受けることができます。
最初に初期化される std::random_device オブジェクトは、次の行で初期化される乱数エンジン std::default_random_engine のシードに使われる非決定論的な一様乱数ビット生成器です。このステップは、エンジンが同じシーケンスを生成しないようにするためのものです。いくつかの乱数エンジンが C++ 数値ライブラリに実装されていますが、時間や空間の必要条件が異なります(完全なリストはこちらを参照してください)。
以下の例では、擬似乱数値を生成するために std::default_random_engine を使用していますが、アプリケーションの制約に応じて特定のアルゴリズムエンジンを初期化することができます。次に、一様分布を初期化し、オプションの引数として min/max 値を渡します。最後に、[10-100] 間隔から 5つのランダムな double をコンソールに出力します。
#include <iomanip>
#include <iostream>
#include <random>
using std::cout;
using std::endl;
using std::setprecision;
// Modify as needed
constexpr int MIN = 10;
constexpr int MAX = 100;
int main() {
  std::random_device rd;
  std::default_random_engine eng(rd());
  std::uniform_real_distribution<double> distr(MIN, MAX);
  for (int n = 0; n < 5; ++n) {
    cout << setprecision(10) << distr(eng) << "\n";
  }
  cout << endl;
  return EXIT_SUCCESS;
}
出力:
73.68930968
24.37712986
40.37815433
77.24899374
94.62192505
テンプレートパラメータとして float、double、long double のいずれかを渡さなかった場合、std::uniform_real_distribution< T > は未定義の振る舞いをすることに注意してください。以下の例は、単精度浮動小数点数を生成するものです。
#include <iomanip>
#include <iostream>
#include <random>
using std::cout;
using std::endl;
using std::setprecision;
// Modify as needed
constexpr int MIN = 10;
constexpr int MAX = 100;
int main() {
  std::random_device rd;
  std::default_random_engine eng(rd());
  std::uniform_real_distribution<float> distr(MIN, MAX);
  for (int n = 0; n < 5; ++n) {
    cout << setprecision(10) << distr(eng) << "\n";
  }
  cout << endl;
  return EXIT_SUCCESS;
}
C++ でランダム double 型を生成するには std::rand 関数を用いる
rand 関数は C 標準ライブラリの乱数生成機能の一部です。高品質の乱数性を必要とするアプリケーションには推奨されませんが、行列やベクトルを乱数で埋めたい場合など、複数のシナリオで利用することができます。
この関数は 0 から RAND_MAX の間の擬似乱数を生成します(どちらも含まれます)。RAND_MAX の値は実装に依存しており、保証される最小値は 32767 しかないため、生成される数値には制約があります。この関数は std::srand でシードされていなければなりません (できれば std::time を用いて現在の時刻を渡してください)。最後に、倍精度の浮動小数点値を生成するための面倒な演算を行うことができます。
#include <iomanip>
#include <iostream>
#include <random>
using std::cout;
using std::endl;
using std::setprecision;
// Modify as needed
constexpr int MIN = 10;
constexpr int MAX = 100;
int main() {
  std::srand(std::time(nullptr));
  for (int i = 0; i < 5; i++)
    cout << setprecision(10)
         << MIN + (double)(rand()) / ((double)(RAND_MAX / (MAX - MIN))) << endl;
  return EXIT_SUCCESS;
}
出力:
84.70076228
11.08804226
20.78055909
74.35545741
18.64741151
