web-dev-qa-db-ja.com

Cでランダムな浮動小数点数を生成する方法

[0,a]からランダムな浮動小数点数を見つける解決策が見つかりません。ここで、aはユーザーが定義した浮動小数点数です。

次のことを試しましたが、正しく動作しないようです。

float x=(float)Rand()/((float)Rand_MAX/a)
25
fragon

試してください:

float x = (float)Rand()/(float)(Rand_MAX/a);

これがどのように機能するかを理解するには、次のことを考慮してください。

N = a random value in [0..Rand_MAX] inclusively.

上記の式(わかりやすくするためにキャストを削除)は次のようになります。

N/(Rand_MAX/a)

しかし、分数による除算は、その分数の逆数で乗算することと同等であるため、これは以下と同等です。

N * (a/Rand_MAX)

次のように書き換えることができます。

a * (N/Rand_MAX)

N/Rand_MAXは常に0.0〜1.0の浮動小数点値です。これにより、0.0〜aの値が生成されます。

または、次を使用することもできます。これは、上で示した内訳を効果的に実行します。実際に何が起こっているのかがはっきりしているので、私は実際にこれを好む(とにかく私には):

float x = ((float)Rand()/(float)(Rand_MAX)) * a;

注:aの浮動小数点表現はexactでなければなりません。そうしないと、aの絶対Edgeケースにヒットしません(近くになります) 。理由に関するざらざらした詳細については この記事 を参照してください。

サンプル

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char *argv[])
{
    srand((unsigned int)time(NULL));

    float a = 5.0;
    for (int i=0;i<20;i++)
        printf("%f\n", ((float)Rand()/(float)(Rand_MAX)) * a);
    return 0;
}

出力

1.625741
3.832026
4.853078
0.687247
0.568085
2.810053
3.561830
3.674827
2.814782
3.047727
3.154944
0.141873
4.464814
0.124696
0.766487
2.349450
2.201889
2.148071
2.624953
2.578719
49
WhozCraig

次のような範囲で[min、max]の範囲で生成することもできます

float float_Rand( float min, float max )
{
    float scale = Rand() / (float) Rand_MAX; /* [0, 1.0] */
    return min + scale * ( max - min );      /* [min, max] */
}
9
baz