在不使用除法/模运算的情况下将随机整数裁剪为一定范围的值

时间:2018-07-21 03:06:33

标签: c++

这可以通过以下方式完成:

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

可以不使用除法来完成此操作吗? 返回值不一定必须匹配,但是必须保留均匀分布。

rndminmax是任意整数。在我的情况下,rnd是一个随机整数。

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

1 个答案:

答案 0 :(得分:2)

如果根据注释,您有一个32位int和rnd输入均匀地分布在-2 ^ 31和2 ^ 31之间,则您可以将输出计算为min + ((((long long)max-(long long)min) * (unsigned long)rnd))>>32,从而将rnd有效地缩放为0..1,并且将值到最小。最大自从您撰写本文以来,您并不关心标准,因此我并不特别关注已签名/未签名的转换做法和警告。只是给出了一个大致的想法-先乘然后移而不是除。

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