Random\Randomizer::nextFloat

半開区間 [0.0, 1.0) から、float の値を取得する

説明

public float Random\Randomizer::nextFloat()

半開区間(左閉右開) に一様に分散した float を等確率に返します。 区間には 0.0 を含み、1.0 までですが、 1.0 そのものは含みません。

返される float の値が、指定された右開の部分区間にある確率は、 部分区間の大きさに比例します。 つまり、返される float が 0.5 より小さい 確率は50%ということです。これは float が 少なくとも 0.5 以上である確率と等しくなります。 同様に、返される float が、区間 0.2 から 0.25 未満までに収まる確率は、ちょうど 5% になります。

この性質を使うと、 Random\Randomizer::nextFloat を活用して返される float が指定された確率 より小さい ことをチェックすることで、 指定された確率でランダムな boolean 値を生成することが可能になります。

注意:

Random\Randomizer::nextFloat が返す可能性がある float の値の範囲は、 Randomizer::getFloat(0.0, 1.0, IntervalBoundary::ClosedOpen) と同じです。

ですが、内部的な Random\Randomizer::nextFloat の実装はより効率的です。

警告

乗算や加算(いわゆるアフィン変換)を使って、 この関数の戻り値を異なる区間に拡大/縮小すると、 結果の値に偏りが出るかもしれません。 なぜなら、浮動小数点数は数直線上で均一に分布するわけではないからです。 全ての値が浮動小数点数によって正確に表現できるとは限らないので、 アフィン変換の結果が暗黙の丸め処理によって求める区間から外れた値になってしまう可能性もあります。 アフィン変換の結果生じる問題の 詳細な説明 は、 Random\Randomizer::getFloat のドキュメントに説明があります。

任意の区間内でランダムな float の値を生成するには、 Random\Randomizer::getFloat を使います。任意の区間内でランダムな整数を生成するには、 Random\Randomizer::getInt を使います。

パラメータ

この関数にはパラメータはありません。

戻り値

半開区間 [0.0, 1.0) (IntervalBoundary::ClosedOpen) に一様に分散した float を等確率に返します。 返される値には 0.0 を含みますが、 1.0 は含みません。

エラー / 例外

  • Random\Randomizer::$engine に存在する Random\Engine::generate メソッド がスローした、あらゆる Throwable がスローされます。

例1 Random\Randomizer::nextFloat の例

<?php
$r = new \Random\Randomizer();

// 返される bool 値は、指定された確率で true になります
$chance = 0.5;

$bool = $r->nextFloat() < $chance;

echo ($bool ? "You won" : "You lost"), "\n";
?>

上の例の出力は、 たとえば以下のようになります。

You won

例2 アフィン変換を使った間違った拡大演算

<?php
final class MaxEngine implements Random\Engine {
    public function generate(): string {
        return "\xff";
    }
}

$randomizer = new \Random\Randomizer(new MaxEngine);

$min = 3.5;
$max = 4.5;

// 以下は絶対やらないで!:
//
// 以下のコードは nextFloat() が 1を絶対に含まない半開区間からサンプリングしたに
// も関わらず、4.5 を出力します。
printf("Wrong scaling: %.17g", $randomizer->nextFloat() * ($max - $min) + $min);

// 正しくは、以下のようにします:
// $randomizer->getFloat($min, $max, \Random\IntervalBoundary::ClosedOpen);
?>

上の例の出力は以下となります。

Wrong scaling: 4.5

参考

  • Random\Randomizer::getFloat