首页 > 解决方案 > 在不使用除法/取模的情况下将随机整数裁剪为一系列值

问题描述

这可以这样做:

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

这可以在不使用除法的情况下完成吗?返回值不一定要匹配,但是必须保持均匀分布。

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

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

标签: c++

解决方案


如果根据评论,您有一个 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;
}

推荐阅读