在[m,n]范围内生成随机偶数

时间:2018-03-12 09:48:15

标签: c random

我一直在寻找C代码来生成[start, end]范围内的一组随机偶数。我试过了,

int random = ((start + rand() % (end - start) / 2)) * 2;

这不起作用,例如,如果范围是[0,4],则0和0都可以。包括4个

int random = (0 + rand() % (4 - 0) / 2) * 2
=> (rand() % 2) * 2
=> 0, 2, ... (never includes 4) but expectation = 0, 2, 4 ...

另一方面,如果我使用,

int random = ((start + rand() % (end - start) / 2) + 1) * 2;

这不起作用,例如,

int random = (0 + (rand() % (4 - 0) / 2) + 1) * 2
=> ((rand() % 4 / 2) + 1) * 2
=> 2, 4,  ... (never includes 0) but expectation = 0, 2, 4 ...

有任何线索吗?如何摆脱这个问题?

4 个答案:

答案 0 :(得分:3)

你太复杂了。由于您使用rand()和模运算符,我假设您不会将其用于加密或安全目的,而是作为一个简单的偶数生成器。

我发现用于生成[0,2n]范围内的随机偶数的公式是使用

s = (rand() % (n + 1)) * 2

示例代码:

#include <stdio.h>

int main() {
    int i, s;
    for(i = 0; i < 100; i++) {
        s = (rand() % 3) * 2;
        printf("%d ", s);
    }
}

它给了我以下输出:

2 2 0 2 4 2 2 0 0 2 4 2 4 2 4 2 0 0 2 2 4 4 0 0 4 4 4 2 2 2 4 0 0 0 4 0 2 2 2 2 0 0 0 4 4 2 4 4 4 0 4 2 2 4 4 0 4 4 2 2 0 0 4 0 4 4 2 0 2 4 0 0 0 0 4 0 4 4 0 4 2 0 0 4 4 0 0 4 4 2 0 0 4 0 2 2 2 0 0 4 0 2 4 2

祝你好运!

答案 1 :(得分:1)

rand() % x会生成[0,x)范围内的数字,因此,如果您想要范围[0,x],请使用rand() % (x+1)

  

范围的常用表示法是将[]用于包含,()用于排除,因此[a,b)将是包含但不包含b的范围。

因此,在您的情况下,只需使用(rand() % 3)*2{0,2,4}

中获取随机数

如果您想要[m,n]范围内的偶数,请使用((m/2) + rand() % ((n-m+2)/2))*2

答案 2 :(得分:1)

我不相信随机数的mod运算符。我更喜欢

rand()

仅依赖于区间中[0, .. , RAND_MAX]的分布 rand()%n而不是[0, .. , n-1]中的[Cost],[Price] money [Profit]=[Price]-[Cost] 间隔[UnderCost]=([Profit]<0)

注意:如果使用此表达式,则应添加适当的强制转换以避免乘法溢出。

另请注意 ISO / IEC 9899:201x(第346页):

  

不能保证产生的随机序列的质量,并且已知一些实现产生具有令人沮丧的非随机低阶位的序列。具有特殊要求的应用应使用已知足以满足其需求的发电机。

答案 3 :(得分:0)

正好和低位,这使得它变得均匀:

n= (rand()%N)&(-2);

并使用开始/停止(范围),值可以偏移:

int n, start= 5, stop= 20+1;
n= ((rand()%(stop-start))+start)&(-2);

后一种计算会生成0到RAND_MAX之间的随机数(此值取决于库,但保证至少为32767)。

如果停止值必须包含在生成的数字范围内,则将1添加到停止值。

该值取值为停止值加上的起始值,然后添加起始值。该值现在在[start,stop]范围内。因为只需要偶数,所以低位被逐出,因为偶数从2开始。

通过生成除最低位之外的所有1的掩码来执行anding-out。由于-1都是1(0xFFF...FFFFF),因此除了这个低位(0xFFF...FFFFE)之外,-2都是1。接下来,使用此掩码执行按位AND操作(&amp;),数字现在在[start,stop]范围内。 QED。