4 種類の間隔すべてで乱数を生成する「最良の」方法を 1 か所に集めたいと考えています。私はこれをグーグルするのにうんざりしています。検索結果は多くのがらくたを出します。関連する結果でさえ、完全に間違っていることが多いページやブログであるか、自任の専門家が技術的な問題について互いに意見を異にする議論を行っているページやブログであり、多くの場合、彼らの「回答」は、さまざまなタイプについて知らないことを明らかにしているように見えます (非公開) 、オープン、セミオープン)間隔の。このような「単純な」質問に対して、C で乱数を生成することに関する悪い情報を読むのにうんざりしています。
一様に分散された浮動小数点数を生成する方法を教えてください。(a、b)、[a、b)、(a、b]、および[a、b]に対する私の典型的な方法(例として「ロングダブル」を使用)は次のとおりです。
long double a=VALUE1,b=VALUE2;
long double x1,x2,x3,x4;
srand((unsigned)time(NULL));
/* x1 will be an element of [a,b] */
x1=((long double)rand()/RAND_MAX)*(b-a) + a;
/* x2 will be an element of [a,b) */
x2=((long double)rand()/((long double)RAND_MAX+1))*(b-a) + a;
/* x3 will be an element of (a,b] */
x3=(((long double)rand()+1)/((long double)RAND_MAX+1))*(b-a) + a;
/* x4 will be an element of (a,b) */
x4=(((long double)rand()+1)/((long double)RAND_MAX+2))*(b-a) + a;
単位間隔 (0,1)、[0,1)、(0,1]、および [0,1] の特殊なケースの場合:
long double x1,x2,x3,x4;
srand((unsigned)time(NULL));
/* x1 will be an element of [0,1] */
x1=((long double)rand()/RAND_MAX);
/* x2 will be an element of [0,1) */
x2=((long double)rand()/((long double)RAND_MAX+1));
/* x3 will be an element of (0,1] */
x3=(((long double)rand()+1)/((long double)RAND_MAX+1));
/* x4 will be an element of (0,1) */
x4=(((long double)rand()+1)/((long double)RAND_MAX+2));
RAND_MAX と rand() の戻り値の両方のキャストが必要だと思います。これは、整数の除算を避けたいという理由だけでなく、それらが int であり、1 つ (または 2 つ) を追加するとオーバーフローする可能性があるためです。
「double」と「float」のバージョンはまったく同じですが、タイプを置き換えているだけだと思います。さまざまな浮動小数点型で発生する微妙な点はありますか?
上記の実装に問題はありますか? もしそうなら、何をどのように修正しますか?
編集:上記の実装は、それらが正しいために必要なテストに合格します(少なくとも64ビットLinuxを実行している64ビットIntel Core 2 Duoマシンでは):x1は0と1の両方を生成でき、x2は0を生成できますが、されていませんx3 は 1 を生成できますが、0 を生成することは確認されておらず、x4 は 0 または 1 を生成することが確認されていません。