10

この質問を調べてソースコードを読んだとき、私は「宣伝されている」ように動作するのかどうか疑問にrandom.py思い始めました。私はそう信じる傾向がありますが、私がそれを読む方法は、本質的に次のように実装されていますrandrangerandintrandrange

start + int(random.random()*(stop-start))

start(との整数値を想定stop)なのでrandrange(1, 10)、1から9までの乱数を返す必要があります。

randint(start, stop)を呼び出しているrandrange(start, stop+1)ため、1〜10の数値が返されます。

私の質問は今です:

もしrandom()戻ってきたら1.0randint(1,10)戻っ11てきますね。

4

3 に答える 3

27

Fromrandom.pyとドキュメント:

"""Get the next random number in the range [0.0, 1.0)."""

)、間隔が排他的1.0であることを示します。つまり、1.0を返すことはありません。

これは数学の一般的な慣習で[あり]、包括的ですが()排他的であり、2つのタイプの括弧は(a, b]またはとして混合できます[a, b)。正式な説明については、ウィキペディア:間隔(数学)を参照してください。

于 2010-06-14T14:19:14.567 に答える
12

random()他の回答は、の結果は常に厳密に以下であると指摘してい1.0ます。しかし、それは話の半分にすぎません。

randrange(n)として計算している場合はint(random() * n)、を満足するPython浮動小数点数、および正の整数については、それが真実であるため、厳密に。よりも小さいこと知っておく必要があります。x0.0 <= x < 1.0n0.0 <= x * n < nint(x * n)n

ここでうまくいかない可能性のあることが2つあります。1つは、を計算するときにx * nn暗黙的にfloatに変換されることです。十分に大きい場合n、その変換によって値が変わる可能性があります。しかし、Pythonソースを見ると、より小さなint(random() * n)メソッドのみが使用されていることがわかります(ここと以下では、プラットフォームがIEEE 754 doublesを使用していると想定しています)。これは、floatへの変換が行われる範囲です。情報を失わないことが保証されています(フロートとして正確に表すことができるため)。n2**53nn

うまくいかない可能性のある2番目のことは、乗算の結果x * n(現在はfloatの積として実行されていることを覚えておいてください)はおそらく正確に表現できないため、丸めが必要になることです。xに十分近い場合1.0、丸めによって結果がそれ自体に切り上げられると考えられnます。

これが起こらないことを確認するにxは、(Pythonが実行されているほとんどすべてのマシンで)の可能な最大値のみを考慮する必要があり1 - 2**-53ます。したがって(1 - 2**-53) * n < n、正の整数nについては、常に真であるため、これを示す必要がありますrandom() * n <= (1 - 2**-53) * n

Proof(Sketch) 。のようkな一意の整数とします。次に、からの次のフロートはです。常に切り捨てられるように、(つまり、製品の実際の丸められていない値)がに近いことを示す必要があります。しかし、少し計算すると、からの距離はであり、からの距離はであることがわかります。ただし(そのように選択したため)、製品に近いため、切り捨てられます(つまり、プラットフォームが何らかの形で最も近い値を実行していると仮定します)k2**(k-1) < n <= 2**knn - 2**(k-53)n*(1-2**53)n - 2**(k-53)nn*(1-2**-53)n2**-53 * nn*(1-2**-53)n - 2**(k-53)(2**k - n) * 2**-532**k - n < nk2**(k-1) < nn - 2**(k-53)

だから私たちは安全です。ふぅ!


補遺(2015-07-04):上記は、IEEE754binary64演算を想定しています。丸めモードは丸めモードです。多くのマシンでは、その仮定はかなり安全です。ただし、浮動小数点にx87 FPUを使用するx86マシン(たとえば、32ビットLinuxのさまざまなフレーバー)では、乗算で二重丸めが行われる可能性があり、その場合はrandom() * n切り上げることができますn。ここでrandom()、可能な最大値を返します。nこれが発生する可能性のある最小のものはn = 2049です。詳細については、http://bugs.python.org/issue24546の説明を参照してください。

于 2010-06-14T21:26:03.537 に答える
3

Pythonドキュメントから:

ほとんどすべてのモジュール関数は、基本関数random()に依存しています。この関数は、セミオープン範囲[0.0、1.0)で均一にランダムフロートを生成します。

フロート数のほぼすべてのPRNGのように。

于 2010-06-14T14:19:29.293 に答える