c – 我应该使用“rand%N”还是“rand()(RAND_MAXN 1)”?

c – 我应该使用“rand%N”还是“rand()(RAND_MAXN 1)”?,第1张

概述我正在阅读 C FAQ并在 question中发现它建议我使用rand()/(RAND_MAX / N 1)而不是更流行的方式是rand()%N. 原因是当N是一个低数字rand()%N将只使用rand()中的几个位. 我在Windows和Linux上测试了N为2的不同方法但是没有注意到差异. #include <stdio.h>#include <stdlib.h>#include <tim 我正在阅读 C FAQ并在 question中发现它建议我使用rand()/(RAND_MAX / N 1)而不是更流行的方式是rand()%N.

原因是当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)”?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1242393.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存