Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么这段代码调用rand()两次以获得至少N个随机位?_C_Random - Fatal编程技术网

C 为什么这段代码调用rand()两次以获得至少N个随机位?

C 为什么这段代码调用rand()两次以获得至少N个随机位?,c,random,C,Random,Pearls编程的第一个问题,第12章,内容如下: 函数的作用是:返回大约15个随机位。使用该函数实现一个函数bigrand()以返回至少30个随机位 这就是作者给出的解决方案: int bigrand() { return RAND_MAX*rand() + rand(); // why add the rand() in the last } 为什么作者在乘法后添加对rand的调用?如果没有额外的rand()结果将是rand\u MAX的倍数,因此甚至不是模糊的随机数 事实上,您

Pearls编程的第一个问题,第12章,内容如下:

函数的作用是:返回大约15个随机位。使用该函数实现一个函数bigrand()以返回至少30个随机位

这就是作者给出的解决方案:

int bigrand()
{
    return RAND_MAX*rand() + rand(); // why add the rand() in the last 
}

为什么作者在乘法后添加对
rand
的调用?

如果没有额外的
rand()
结果将是
rand\u MAX
的倍数,因此甚至不是模糊的随机数

事实上,您显示的代码并不完全正确,它应该是正确的

int bigrand()
{
    return (RAND_MAX+1)*rand() + rand(); // why add the rand() in the last 
}
RAND_MAX
对于某些x几乎总是2^x-1。在没有
+1
的情况下,
RAND_MAX*RAND()
RAND()
之间存在重叠,因此您可以有效地添加两个随机数,这会扭曲随机性(例如,将两个掷骰子相加)

添加额外的1使其为2的幂,因此
RAND_MAX*RAND()
的底部x位均为0;附加的
rand()
填充底部位。这更像是将第一个rand()左移,或将第二个rand()左移


注意,该方法仅用于生成一点非关键测试数据,但如果需要真正的线性随机性,则不应使用该方法;如果需要30位,则应使用真正的30位(或更多)随机数生成器。

此解决方案所针对的问题如下:

函数的作用是:返回大约15个随机位。使用该函数实现一个函数bigrand()以返回至少30个随机位

一种简单的方法是组合2个
rand()
调用的输出,填充必要的位数,每次15位。这个

RAND_MAX * rand()
填充最重要的15位,加法处理剩余的部分

如果RAND_MAX的值产生
int
类型溢出,这当然是未定义的行为(在我的系统上,我发现
\define RAND_MAX 0x7fffff
)。如果
rand
规范更严格一些,例如说只有最低的15位是随机的(这是一种不太可能且虚构的情况),我们可以:

int bigrand(void)
{
    return ((rand() & 0x7fff) << 15) | (rand() & 0x7fff);
}
int-bigrand(无效)
{

返回((rand()&0x7fff)可能是为了提供更多的“随机性”/生成更大的数字。
rand()
在大多数实现中,只填充int的前16位。如果只有六面骰子,如何生成大于6的随机数?如果只有
RAND_MAX
侧面PRNG实现,如何生成大于
RAND_MAX
的随机数?是的,这是为了确保在RAND_MAX=32767的情况下l使用
(RAND_MAX+1)*RAND()^RAND()
填充整个32位更好,如果
RAND_MAX>0x7fff