原因是当N是一个低数字rand()%N将只使用rand()中的几个位.
我在windows和linux上测试了N为2的不同方法但是没有注意到差异.
#include <stdio.h>#include <stdlib.h>#include <time.h>#define N 2int main(voID){ srand(0); printf("rand() %% N:\n"); for (int i = 0; i < 40; ++i) { printf("%d ",rand() % N); } putchar('\n'); srand(0); printf("rand() / (RAND_MAX / N + 1):\n"); for (int i = 0; i < 40; ++i) { printf("%d ",rand() / (RAND_MAX / N + 1)); } putchar('\n'); return 0;}
输出是这个(在我的gnu / linux机器上):
rand() % N:1 0 1 1 1 1 0 0 1 1 0 1 0 1 1 0 0 0 0 0 1 0 1 1 0 0 0 1 1 1 1 0 0 0 1 1 1 0 1 0 rand() / (RAND_MAX / N + 1):1 0 1 1 1 0 0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 0 0 1 0 0 0 0 1 0 1 1 1 0 1 1 0 1 0 1
两种选择对我来说都是完全随机的.甚至看起来第二种方法比兰特%N更差.
我应该使用rand()%N还是rand()/(RAND_MAX / N 1)?
解决方法 如果N是2的幂,则使用余数技术通常是安全的(RAND_MAX通常是2的幂-1,因此整个范围具有两个长度的幂).更一般地,N必须除以rand()的范围以避免偏差.否则,无论rand()的质量如何,都会遇到this problem.简而言之,问题在于你将该范围切割成长度为N的多个“部分”,如果N不分割范围则最后部分将不完整.因此,从该部分“切断”的数字不太可能发生,因为它们可以从中生成更少的“部分”.
不幸的是rand()/(RAND_MAX / N 1)也被破坏了(几乎以同样的方式),所以真正的答案是:不要使用它们中的任何一个.
上面提到的问题非常重要,除非Y除以X,否则无法在Y结果上均匀分布X个不同的值.您可以通过拒绝一部分随机样本来修复它,使Y除以新的X.
总结以上是内存溢出为你收集整理的c – 我应该使用“rand%N”还是“rand()/(RAND_MAX / N 1)”?全部内容,希望文章能够帮你解决c – 我应该使用“rand%N”还是“rand()/(RAND_MAX / N 1)”?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)