乐闻世界logo
搜索文章和话题

Why is rand()%6 biased?

2 个月前提问
2 个月前修改
浏览次数25

1个答案

1

当使用 rand() 函数生成随机数,并通过取模操作 %6 试图获取一个范围从0到5的随机数时,确实存在偏差。这种偏差的主要原因在于 rand() 产生的随机数范围和模数的不匹配。

rand() 函数通常返回一个在0到RAND_MAX(一个系统定义的常量,例如在许多系统中为32767)之间的整数。当你执行 rand() % 6 操作时,你是在尝试把 rand() 返回的均匀分布的随机数范围压缩到0到5的范围内。

但问题在于,32767(假设RAND_MAX为32767)不能被6整除,整除后最大为5459,余数为1。这意味着0到5中的一些数字会比其他数字多出一种可能的随机数产生方式。具体来说,rand() 返回的值在 [0, 5459]、[5460, 10919]、[10920, 16379]、[16380, 21839]、[21840, 27299] 和 [27300, 32766] 这几个区间内时,取模的结果分别为0、1、2、3、4和5。但由于32767是最后一个数字,并且取模结果是1,这使得结果为1的情况比其他数字多一种可能性。

这导致 rand() % 6 中0到5的数字并不是完全均匀分布的。特别是数字1的出现概率会稍微高于其他数字(0、2、3、4、5)。

为了在使用 rand() 时获得更均匀的分布,可以使用如下的方法:

  1. 使用更复杂的随机数生成算法,比如 Mersenne Twister(通常通过 std::mt19937 实现)。
  2. 使用拒绝采样方法,即只在 rand() 返回的值落在一个可以被6整除的最大范围内时才计算模数。例如,可以只在 rand() 返回的值小于32766的情况下计算 rand() % 6(32766是小于32767的最大的可以被6整除的数)。

通过这些方法,可以尽可能减少取模操作带来的不均匀分布问题,从而生成更加均匀分布的随机数。

2024年7月19日 19:50 回复

你的答案