0.1 から 1.0 の間の乱数を生成しようとしています。rand.randint
整数を返すため使用できません。も試しrandom.uniform(0.1,1.0)
ましたが、値 >= 0.1 および < 1.0 を返します。検索には 1.0 も含まれているため、これは使用できません。
他の誰かがこの問題について考えを持っていますか?
0.1 から 1.0 の間の乱数を生成しようとしています。rand.randint
整数を返すため使用できません。も試しrandom.uniform(0.1,1.0)
ましたが、値 >= 0.1 および < 1.0 を返します。検索には 1.0 も含まれているため、これは使用できません。
他の誰かがこの問題について考えを持っていますか?
Random.uniform()
ただ:
def uniform(self, a, b):
"Get a random number in the range [a, b) or [a, b] depending on rounding."
return a + (b-a) * self.random()
whereself.random()
は範囲内の乱数を返します[0.0, 1.0)
。
Python (および他の多くの言語) は、浮動小数点を使用して実数を表します。どのよう0.1
に表現されるかは、ドキュメントで詳しく説明されています。
from __future__ import division
BPF = 53 # assume IEEE 754 double-precision binary floating-point format
N = BPF + 3
assert 0.1 == 7205759403792794 / 2 ** N
精度を失うことなく[0.1, 1]
(包括的)
で乱数を見つけることができます。randint()
n, m = 7205759403792794, 2 ** N
f = randint(n, m) / m
randint(n, m)
[n, m]
は(包括的)にランダムな整数を返すため、上記のメソッドは にすべての浮動小数点数を返す可能性があり[0.1, 1]
ます。
x
別の方法は、そのような最小のものを見つけてx > 1
使用することです。
f = uniform(.1, x)
while f > 1:
f = uniform(.1, x)
x
精度の低下を防ぎ、呼び出し回数を減らすために、最小値にする必要がありますuniform()
。
import sys
# from itertools import count
# decimal.Decimal(1).next_plus() analog
# x = next(x for i in count(1) for x in [(2**BPF + i) / 2**BPF] if x > 1)
x = 1 + sys.float_info.epsilon
どちらのソリューションも、ランダム分布の均一性を維持します (スキューなし)。
標準的な方法はrandom.random() * 0.9 + 0.1
(random.uniform()
内部的にこれを行います)です。これは、0.1 から 1.0 の間の数値を上限なしで返します。
ちょっと待って!0.1 (別名 ¹/₁₀) には明確な 2 進数表現 (10 進数の 1/3) がありません! したがって、コンピューターが内部的に表現できないという理由だけで、真の 0.1 を取得することはできません。ごめん ;-)
random.randint(1, 10)/100.0 を試してください