【问题标题】:Small range of random numbers for float/double, good for integral types (C++, VS2010)浮点/双精度的小范围随机数,适用于整数类型(C++,VS2010)
【发布时间】:2013-01-01 12:40:46
【问题描述】:

我正在尝试使用 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 向量填充的数字范围要小得多。

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

【问题讨论】:

    标签: c++ visual-studio-2010 templates random numeric-limits


    【解决方案1】:

    您正在生成一个介于numeric_limits&lt;T&gt;::min()numeric_limits&lt;T&gt;::max() 之间的值。但numeric_limits&lt;T&gt;::min() 可能不是您期望的那样:对于浮点类型,它是最小的 归一化值,非常接近于零。所以你的代码只能得到正浮点数。对于float,这将是最多约 3.4e38 的数字。这些数字中的绝大多数都超过 1e37,因此这些是您获得的大部分结果是有道理的。

    要获得可能的有限值,您需要使用从numeric_limits&lt;T&gt;::lowest()numeric_limits&lt;T&gt;::max() 的范围。但这会导致未定义的行为,因为传递给uniform_real_distribution 的范围的大小必须达到numeric_limits&lt;RealType&gt;::max()

    因此,您需要以不同的方式生成数字。例如,您可以生成一个介于 0 和numeric_limits&lt;T&gt;::max() 之间的非负数,并分别生成其符号。

    【讨论】:

    • 那么如何使用浮点数/双精度数的全部范围来生成随机数?谢谢,奥伦
    • @OrenSarid:我之前的回答错过了这里的真正问题。请参阅我编辑的答案。
    猜你喜欢
    • 2012-04-01
    • 1970-01-01
    • 2013-03-16
    • 2011-10-24
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多