我一直在寻找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 ...
有任何线索吗?如何摆脱这个问题?
答案 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。