1. ホーム
  2. c#

[解決済み] C#でランダムなfloatを生成する最適な方法【非公開

2022-03-07 09:46:15

質問

C#でランダムなfloatを生成する最も良い方法は何ですか?

Update: float.Minvalue から float.Maxvalue までのランダムな浮動小数点数が欲しいのですが、どうすればいいですか?私はいくつかの数学的手法のユニットテストでこれらの数字を使用しています。

どのように解決するのですか?

ベストな方法、狂いのない価値観。 浮動小数点数直線上の表現可能な区間に対して分配される (連続数直線に関しては明らかに非一様であるため、"uniform" を削除しました)。

static float NextFloat(Random random)
{
    double mantissa = (random.NextDouble() * 2.0) - 1.0;
    // choose -149 instead of -126 to also generate subnormal floats (*)
    double exponent = Math.Pow(2.0, random.Next(-126, 128));
    return (float)(mantissa * exponent);
}

(*) ... チェック こちら サブノーマルフロート用

警告: 正の無限大も生成されます! 念のため、指数を127にしましょう。

もう1つの方法は、ファジングに役立つ可能性のある、おかしな値(ビットパターンの一様分布)を得ることができます。

static float NextFloat(Random random)
{
    var buffer = new byte[4];
    random.NextBytes(buffer);
    return BitConverter.ToSingle(buffer,0);
}

前バージョンからの改良点として、quot;crazed"値(無限大でもNaNでもない)を作らず、かつ高速(浮動小数点数直線上の表現可能な間隔に関しても分散)であることが挙げられます。

public static float Generate(Random prng)
{
    var sign = prng.Next(2);
    var exponent = prng.Next((1 << 8) - 1); // do not generate 0xFF (infinities and NaN)
    var mantissa = prng.Next(1 << 23);

    var bits = (sign << 31) + (exponent << 23) + mantissa;
    return IntBitsToFloat(bits);
}

private static float IntBitsToFloat(int bits)
{
    unsafe
    {
        return *(float*) &bits;
    }
}

最も役に立たない方法。

static float NextFloat(Random random)
{
    // Not a uniform distribution w.r.t. the binary floating-point number line
    // which makes sense given that NextDouble is uniform from 0.0 to 1.0.
    // Uniform w.r.t. a continuous number line.
    //
    // The range produced by this method is 6.8e38.
    //
    // Therefore if NextDouble produces values in the range of 0.0 to 0.1
    // 10% of the time, we will only produce numbers less than 1e38 about
    // 10% of the time, which does not make sense.
    var result = (random.NextDouble()
                  * (Single.MaxValue - (double)Single.MinValue))
                  + Single.MinValue;
    return (float)result;
}

浮動小数点数線から。 インテル® アーキテクチャ・ソフトウェア開発者向けマニュアル 第1巻: 基本アーキテクチャ. 連続した2進浮動小数点数は直線的に異なるため、Y軸は対数(底2)になっています。