首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >随机数函数(C++11)

随机数函数(C++11)
EN

Stack Overflow用户
提问于 2013-12-29 17:08:48
回答 2查看 549关注 0票数 1

我正在重写这个函数:

代码语言:javascript
复制
long rng(long low, long high)
{
    return low + long((high - low + 1) * double(rand() / double(RAND_MAX + 1.0)));
}

将其更新到C++11和Mersenne。

代码语言:javascript
复制
long rng(long low, long high)
{
    static std::mt19937 rnumber; // Mersenne Twister
    std::uniform_int_distribution<unsigned> u (low, high);
    return u(rnumber);
}

现在看来这是可行的,但是我的C++11书指出,在类似的情况下,引擎和分发服务器都应该是“静态的”。问题是我想用不同的范围调用函数,如果我使分配器是静态的,那么范围总是相同的。

那么,应该如何妥善处理这一问题呢?

另外两个问题:

  • 为什么Stroustrup的书似乎建议我应该使用{低,高}而不是(低,高)?有什么关系呢?
  • 用gcc 4.8.1而没有优化兰特是Mersenne的两倍,而-O3 rand有同样的性能,而Mersenne甚至比rand更快,这是可信的吗?
EN

回答 2

Stack Overflow用户

发布于 2013-12-29 18:22:53

分布对象是需要初始化的对象。如果您可以重用它们,那么重用它们将比每次使用时创建它们更有效。由于随机数的典型用法是为相同的范围生成多个值,因此可以删除额外的构造。当用不同的随机数生成器替换rand()的使用时,传递对象可能是不可行的。对于新创建的代码,保持足够的上下文以拥有一个分发对象也是合理的。

关于你对问题的补充:

  1. 使用大括号而不是括号使用统一的初始化语法(当然,这远不是普遍适用的)。其中一个好处是它拒绝缩小转换范围。
  2. C++11随机数生成器中的计算可能是内联的。可能有足够的优化空间让gcc用-O3更快地完成计算。当然,编译器也有可能决定不使用随机数的结果,而实际上使用的是elides。
票数 1
EN

Stack Overflow用户

发布于 2014-09-08 17:23:02

您不必事先指定发行版的限制。

代码语言:javascript
复制
#include <iostream>
#include <ostream>
#include <random>

unsigned long rng(unsigned long low, unsigned long high)
{
    static std::mt19937 engine((std::random_device()()));
    static std::uniform_int_distribution<unsigned long> dist;

    std::uniform_int_distribution<unsigned long>::param_type p(low, high);

    return dist(engine, p);
}

int main()
{
    const unsigned int n = 10;
    const int m = 24;
    for (unsigned int k = 2; k != n + 1; ++k)
    {
        for (int j = 0; j != m; ++j)
        {
            // Print out 24 numbers from the range [0, k)
            std::cout << rng(0, k - 1) << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20827812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档