我正在尝试使用random.uniform而不是random.getrandbits来以50/50的概率生成0或1。
这就是我所拥有的
0 if random.uniform(0, 1e-323) == 0.0 else 1
但是,如果我运行了足够长的时间,则平均值约为70%以生成1。如下所示:
sum(0 if random.uniform(0, 1e-323) == 0.0
else 1
for _ in xrange(1000)) / 1000.0 # --> 0.737
如果将其更改为1e-324,它将始终为0。如果将其更改为1e-322,则平均值为〜%90。
我做了一个肮脏的程序,试图通过将其除以并乘以几次来找到1e-322和1e-324之间的最佳点:
v = 1e-323
n_runs = 100000
target = n_runs/2
result = 0
while True:
result = sum(0 if random.uniform(0, v) == 0.0 else 1 for _ in xrange(n_runs))
if result > target:
v /= 1.5
elif result < target:
v *= 1.5 / 1.4
else:
break
print v
最终以4.94065645841e-324
但是,如果我运行足够的时间,那仍然是错误的。
没有我编写的肮脏脚本,是否可以找到该编号?我知道Python在sys.float_info.min中显示了一个内部最小浮点值,在我的PC中是2.22507385851e-308。但是我看不到如何使用它来解决这个问题。
很抱歉,这比起一个适当的问题,更像是一个难题,但我本人无法回答。
python大神给出的解决方案
我知道Python在sys.float_info.min中显示了一个内部最小浮点值,在我的PC中是2.22507385851e-308。但是我看不到如何使用它来解决这个问题。
2.22507385851e-308
不是最小的正浮点值,它是最小的正标准化浮点值。最小的正浮动值是该值的2-52倍,即接近5e-324。
2-52被称为“机器epsilon”,通常将浮点类型的“ min”称为一个值,该值是所有可比较值中的最小值(即-inf
)或最小值的有限值(即-max
)或最小的正值。
然后,您面临的下一个问题是random.uniform
的一致性不高。当您将其传递给归一化的数字时,它可能工作正常,但是,如果传递给它的是最小的正可表示浮点数,则其内部进行的计算可能非常近似,从而导致其行为不同于文档中所述。尽管根据您的“脏脚本”的结果,它似乎可以正常工作。