代码之家  ›  专栏  ›  技术社区  ›  Pavel P

将随机整数剪裁为一个值范围,而不使用除法/模

c++
  •  0
  • Pavel P  · 技术社区  · 6 年前

    可以这样做:

    int clamp(int rnd, int min, int max)
    {
        return min + rnd % (max - min + 1);
    }
    

    不用除法就能做到吗? 返回值不一定要匹配,但是必须保持均匀分布。

    rnd 我是说, min ,和 max 是任意整数。 RND公司 在我的例子中是一个随机整数。

    一种可能的解决方案是转换为 double 范围 [0...1) 使用 std::ldexp 然后乘法,但我想知道是否有一个更简单的解决方案,不涉及浮点数和/或除法。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Pavel P    6 年前

    如果根据注释,您有一个32位int和rnd输入,均匀分布在-2^31和2^31之间,您可以将输出计算为 min + ((((long long)max-(long long)min) * (unsigned long)rnd))>>32 它可以有效地将rnd扩展到0..1,将值扩展到min..max。因为您编写了一篇文章,所以不关心标准,所以我不需要特别关注有符号/无符号转换实践和警告只是给出了一个大致的概念-先乘,然后移位,而不是除法。

    int clamp(uint32_t rnd, int min, int max)
    {
        return min + (1ull*rnd*(max - min + 1)) >> 32;
    }