杭州思拓网站建设,大连网站建设大连,免费的平面设计网站,应用软件设计过程老司机的新问题#xff0c;取得[min, max]范围的随机数。C版本的rand函数很不容易用对#xff0c;直接用rand() % (max - min 1) min#xff0c;这个公式不对。这个公式与取最低位的算法相同#xff0c;而随机数的最低几位不一定等概率。Donald Knuth博士教导我们正确的用…老司机的新问题取得[min, max]范围的随机数。C版本的rand函数很不容易用对直接用rand() % (max - min 1) min这个公式不对。这个公式与取最低位的算法相同而随机数的最低几位不一定等概率。Donald Knuth博士教导我们正确的用法是 rand() / ((RAND_MAX 1U) / (max - min 1)) min这把rand的所有可能的值分成max - min个桶每个数落入0号到max - 1号桶的概率相等。C中有std::uniform_int_distribution可以直接取一定范围正态分布的随机数我也没有深究过上面那个公式是否不正确。结果还真的不正确。因为大多数情况下RAND_MAX / (max - min 1) 都除不尽 小数部分被舍去后数值偏小。比如[RAND_MAX / 2, RAND_MAX / 2 1]这组如果 RAND_MAX 11那么[0 - 4]的rand()被认为是5概率是5/11而5-11被认为是6概率是6/11。当采样次数与RAND_MAX同数量级时这个概率差就显示出来了。这个值有时可能只有32767。大部分平台上这个值 为INT_MAX。做个游戏什么的还没有问题一但用于统计数据这就出错了。stackoverflow上有人给出了正确的算法注意这个算法是[0, max]的区间。https://stackoverflow.com/questions/2509679/how-to-generate-a-random-integer-number-from-within-a-range#6852396stackoverflow.com本质上很简单就是把RAND_MAX除不尽的部分从rand中消去。long random_at_most(long max) {unsigned long// max RAND_MAX ULONG_MAX, so this is okay.num_bins (unsigned long) max 1,num_rand (unsigned long) RAND_MAX 1,bin_size num_rand / num_bins,defect num_rand % num_bins;long x;do {x random();}// This is carefully written not to overflowwhile (num_rand - defect (unsigned long)x);// Truncated division is intentionalreturn x / bin_size;
}
当RAND_MAX不够大时怎么办可以通过以下公式扩展随机数。unsigned long newrand rand() * ((unsigned long)RAND_MAX 1) rand()
注意RAND_MAX的取值不要溢出了。