c++ - 随机数生成的快速模数替换是什么?

目前我使用的是非常快的 XorShift 算法:

inline uint r() {
  static uint y = 2463534242u; // seed
  y ^= (y<<13);
  y ^= (y>>17);
  y ^= (y<<5);
  return y;
}

现在我想从区间 [0, n) 生成一个整数。我当然可以这样做:

r() % n

但这很慢。有没有更快的方法?

附言 区间内不同数字概率的小幅不等式是可以接受的。

最佳答案

如果您的n 低于模板的编译器递归深度,您可以尝试来自The fastest way to generate a random permutation 的方法。并让编译器使用更轻量级的操作优化模数。

对于较大的n,您可以使用https://arxiv.org/pdf/1805.10941.pdf 中的方法,其中大部分时间除法运算被乘法(加上小的按位运算)代替。

uint32_t NextInt(const uint32_t modulo) {
    const uint32_t mask = uint32_t(-1);
    uint32_t x = r();
    uint64_t m = x * uint64_t(modulo);
    if(m < modulo) {
        final uint32_t t = uint32_t(-modulo) % modulo;
        while(m < t) {
            x = r();
            m = x * uint64_t(modulo);
        }
    }
    return uint32_t(m >> 32);
}

https://stackoverflow.com/questions/4669039/

相关文章:

maven-3 - mvn clean install + java.lang.NoClassDef

unicode - 无法使用自定义操作将 MSI 安装到用户名中包含非 ascii 字符的非管理员

c# - 从 Datagrid 插入和更新 SQL Server

r - 如何使用 RODBC 或 RCurl 从 R 中受密码保护的 Sharepoint 2007

asp.net - "Invalid use of response filter"压缩来自 IHt

.net - .NET 资源文件字符串是否被保留?

visual-studio-2010 - TFS Team Build MSTest 运行持续时间太

.net - ToString() 和调试器的字符串可视化工具

php - soap 信封是如何生成的,为什么 .NET 和 php 客户端会生成/接收不同的 so

java - 为什么当我在另一台计算机上加载我的工作区时 Eclipse 显示错误?