visual studio 2010 -浮点/双精度随机数的小范围,适用于整型(c++, VS2010)

visual studio 2010 - Small range of random numbers for float/double, good for integral types (C++, VS2010)

本文关键字:适用于 范围 整型 VS2010 c++ 2010 studio 浮点 随机数 双精度 visual      更新时间:2023-10-16

我试图在VS2010中使用基于类型的随机数创建模板。我使用下面的代码:

template<class BaseT>
struct distribution
{ // general case, assuming T is of integral type
    typedef std::tr1::uniform_int<BaseT> dist_type;
};
template<>
struct distribution<float>
{ // float case
    typedef std::tr1::uniform_real<float> dist_type;
};
template<>
struct distribution<double>
{ // double case
    typedef std::tr1::uniform_real_distribution<double> dist_type;
};
template<class BaseT>
class BaseTypeRandomizer
{
public:
    BaseTypeRandomizer() : mEngine(std::time(0))
    {
    }
    void CreateValues(std::vector<BaseT>& Values, size_t nValues)
    {
        typedef typename distribution<BaseT>::dist_type distro_type;
        std::random_device Engine;
        distro_type dist(std::numeric_limits<BaseT>::min(), std::numeric_limits<BaseT>::max());
        for (size_t iVal = 0; iVal < nValues; ++iVal)
        {
            Values[iVal] = dist(Engine);
        }
    }
};

不幸的是,为char/int/long等(整型)创建BaseTypeRandomizer对象会返回覆盖整个范围的数字,但对于浮点数和双精度数则不会。浮点数都在1e+379e+38之间,双精度数都在1e+3072e+308之间(或者至少都在附近)。在VS调试器中检查dist对象显示限制是正确的,但是Values向量填充的数字范围要小得多。

有没有人知道为什么限制不能正常工作?

生成的值介于numeric_limits<T>::min()numeric_limits<T>::max()之间。但是numeric_limits<T>::min()可能不是您期望的那样:对于浮点类型,它是最小的规范化值,非常接近于零。所以你的代码只能得到正的浮点数。对于float,这将是大约3.4e38的数字。这些数字中的绝大多数都大于1e37,所以这些是您得到的大多数结果是有道理的。

要获得可能的有限值,您需要使用从numeric_limits<T>::lowest()numeric_limits<T>::max()的范围。但是这会导致未定义的行为,因为传递给uniform_real_distribution的范围的大小必须不超过numeric_limits<RealType>::max()

所以你需要用另一种方式生成数字。例如,您可以生成0到numeric_limits<T>::max()之间的非负数,并单独生成其符号。