【发布时间】:2017-06-29 01:14:20
【问题描述】:
我正在尝试为所有可表示的有限值生成概率大致相等的随机双精度数。我相信这类似于随机签名的exponential_distribution,uniform_distribution 将不起作用,因为可表示的双精度数不是均匀分布的。我有这个 hacky 代码,似乎可以做我想做的事:
#include <cmath>
#include <iostream>
#include <random>
template < class GEN >
double double_distribution (GEN& generator)
{
using gen_type = typename GEN::result_type;
static_assert (sizeof (gen_type) == sizeof (double), "");
union {gen_type g; double f;} result;
do {
result.g = generator();
} while (!std::isfinite (result.f));
return result.f;
}
int main() {
std::mt19937_64 mt ((std::random_device())());
for (int n = 0; n < 10; ++n) {
std::cout << double_distribution (mt) << ' ';
}
std::cout << '\n';
}
但我想知道是否有一种更简单的方法可以使用 STL 现有的 RandomNumberDistribution 类之一来近似此值?
【问题讨论】:
-
你不能从
[-1, 1]得到一个统一的范围,然后乘以你的最大值吗? -
@NathanOliver:也许,所有可能的双打都可以这样生成吗?直觉上,似乎将范围限制为
[-1,1]会限制熵,乘以常数不会增加熵,但也许我遗漏了一些东西。 -
@atb -- 你的直觉是对的。
[-1,1]中的可表示值比[-DBL_MAX, DBL_MAX]中的少。对于存在性证明,只需考虑[-1,1]中的所有值也在[-DBL_ MAX, DBL_MAX]中,而 2.0 在后者而不是前者。更不用说更多的价值了...... -
您还需要过滤掉 NaN。
-
我面前没有,但是如果我没记错的话,在浮点值的IEEE表示中,所有的有限值,非NaN值都用连续的位值表示.也就是说,如果您将 RNG 限制在 64 位值的适当子范围内,您将只能获得有限的非 NaN 值。