C++ でランダムな浮動小数点数を生成する方法
この記事では、C++ でランダムな浮動小数点数を生成する方法をいくつか説明します。
C++11 <random>
ライブラリを使用してランダムな浮動小数点数を生成する
このメソッドは現代の C++ で高品質の乱数を生成するために推奨されている方法です。まず、std::random_device
オブジェクトを初期化する必要があります。これはランダムエンジンのシード用に非決定論的なランダムビットを生成します。この例では std::default_random_engine
を用いて擬似乱数を生成していますが、特定のアルゴリズムエンジンを宣言することもできます (全リストこちらを参照してください)。次に、一様分布を初期化し、オプションの引数として min/max 値を渡します。
その結果、5つのランダムフロートをコンソールに出力します。
#include <iomanip>
#include <iostream>
#include <random>
using std::cout;
using std::endl;
using std::setprecision;
constexpr int FLOAT_MIN = 10;
constexpr int FLOAT_MAX = 100;
int main() {
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_real_distribution<> distr(FLOAT_MIN, FLOAT_MAX);
for (int n = 0; n < 5; ++n) {
cout << setprecision(10) << distr(eng) << "\n";
}
return EXIT_SUCCESS;
}
出力:
19.54383877
92.41870106
92.42645927
93.53035308
39.09127952
前回のバージョンでは、実際には倍精度の浮動小数点値(64 ビット
)を生成していました。float
の型は、std::uniform_real_distribution< T >
に float
、double
、long double
を指定することでカスタマイズすることができます。ただし、引数がこれらのいずれかでない場合は、未定義のの動作が発生することに注意してください。次の例は、単精度浮動小数点数を生成するものです。
#include <iomanip>
#include <iostream>
#include <random>
using std::cout;
using std::endl;
using std::setprecision;
constexpr int FLOAT_MIN = 10;
constexpr int FLOAT_MAX = 100;
int main() {
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_real_distribution<float> distr(FLOAT_MIN, FLOAT_MAX);
for (int n = 0; n < 5; ++n) {
cout << setprecision(10) << distr(eng) << "\n";
}
return EXIT_SUCCESS;
}
ランダムな浮動小数点数を生成するには rand
関数を用いる
rand
関数は C ライブラリから提供されるものであり、質の高い乱数性が必要な場合には推奨されません。この関数は 0 から RAND_MAX
の間の擬似乱数を生成します(どちらも含む)。RAND_MAX
の値は実装に依存し、保証される最小値は 32767 しかないので、rand
で生成される数値は制約のある乱数となります。この関数は std::srand
でシードされていなければならないことに注意してください(できれば現在時刻を引数に渡すことが望ましい)。
#include <iomanip>
#include <iostream>
#include <random>
using std::cout;
using std::endl;
using std::setprecision;
constexpr int FLOAT_MIN = 10;
constexpr int FLOAT_MAX = 100;
int main() {
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_real_distribution<float> distr(FLOAT_MIN, FLOAT_MAX);
for (int n = 0; n < 5; ++n) {
cout << setprecision(10) << distr(eng) << "\n";
}
cout << endl;
std::srand(std::time(nullptr));
for (int i = 0; i < 5; i++)
cout << setprecision(10)
<< FLOAT_MIN +
(float)(rand()) / ((float)(RAND_MAX / (FLOAT_MAX - FLOAT_MIN)))
<< endl;
return EXIT_SUCCESS;
}