【发布时间】:2019-10-10 11:43:38
【问题描述】:
我一直在研究 C11 中 <stdlib.h> 中的 int rand() 函数,当时我偶然发现了以下 cppreference-example 用于滚动六面骰子。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
srand(time(NULL)); // use current time as seed for random generator
int random_variable = rand();
printf("Random value on [0,%d]: %d\n", RAND_MAX, random_variable);
// roll a 6-sided die 20 times
for (int n=0; n != 20; ++n) {
int x = 7;
while(x > 6)
x = 1 + rand()/((RAND_MAX + 1u)/6); // Note: 1+rand()%6 is biased
printf("%d ", x);
}
}
具体这部分:
[...]
while(x > 6)
x = 1 + rand()/((RAND_MAX + 1u)/6); // Note: 1+rand()%6 is biased
[...]
问题:
为什么要添加
+ 1u?因为rand()是[0,RAND_MAX]我猜 那在做什么rand()/(RAND_MAX/6) -> [0,RAND_MAX/(RAND_MAX/6)] -> [0,6]?和 因为它是整数除法(LARGE/(LARGE+small)) < 1 -> 0,添加1u给它所需的[0,5]范围?在上一个问题的基础上,假设
[0,5]、1 + (rand()/((RAND_MAX+1u)/6))应该只经过[1,6]并且永远不会触发第二个循环?
一直在四处寻找rand() 是否在某个时候返回了float,但是
这似乎是对旧代码的巨大破坏?我猜是支票
如果您添加 1.0f 而不是 1u 使其成为浮点数,则有意义
分配?
试图把我的头包裹起来,有一种我可能会失踪的感觉 东西..
(P.s. 这不是任何安全关键的基础,我只是在探索 标准库。 D.s)
【问题讨论】:
-
不,
rand从未返回浮点数。 -
"为什么要加+1u"怎么知道呢?代码应该做什么?
-
rand() 返回 [0..RAND_MAX] 范围内的数字,因此存在 RAND_MAX+1 个可能的值。 here 解释了为什么 % 运算符有偏见。
-
@Lundin *咳嗽*
Note: 1+rand()%6 is biased -
"应该只经过 [1,6] 并且永远不会触发第二个循环?" --> 假装
RAND_MAX == 9浏览代码。