【问题标题】:Generating N random numbers from rand2()从 rand2() 生成 N 个随机数
【发布时间】:2019-06-28 00:49:54
【问题描述】:

以下randn 函数用于生成随机数,但我想知道它是如何工作的。那里的循环中发生了什么,它如何影响生成的随机值?

int rand2() {
    return rand() & 1;
}

int randn(int N) {
    int add = 0;
    int ref = 1;
    for (int i = 0; i < N; i++) {
        add = add + rand2() * ref;
        ref = ref * 2;
    }
    return add % N;
}

int main() {
    srand(time(NULL));
    printf("%d, ", randn(5));
    return 0;
}

【问题讨论】:

  • 它一次生成一位非常糟糕的随机数。避免它。
  • 当然,但只是想知道它是如何工作的? :)
  • 问:“它是如何工作的?” 答:不太好。使用int randn(int N) { return rand() % N; } 实际上你会得到更好的结果(和更少的代码)如果你想做正确的工作,检查你的系统是否提供了arc4random_uniform 函数。
  • 问题是我必须使用rand2() 函数作为randn() 的唯一输入,这是一个面试问题
  • 如何正确地完成第二部分,见pcg-random.org/posts/bounded-rands.html

标签: c random


【解决方案1】:

rand2 生成01,因此是随机位生成器。

randn 使用rand2,并以二进制方式执行此操作。因此,输入N 是二进制值的长度,它会为每个数字获取一些随机位。但是这个值在每次迭代结束时都会转换为十进制。

N = 5;

  1. rand2 返回0ref=1add=00 二进制)
  2. rand2 返回 1ref=2add=210 二进制)
  3. rand2 返回 1ref=4add=6110 二进制)
  4. rand2 返回 0ref=8add=60110 二进制)
  5. rand2 返回 1ref=16add=2210110 二进制)

ref根据数字控制二进制到十进制的转换,其值为ref = 2^i。它在所有迭代中的值表示二进制中各自位置的1 位的值,因此二进制中的place value。当rand2结果为1时,ref值与add的值相加,当rand2结果为0时,ref被忽略,add的值保持不变.

但是最后randn返回add % N,也就是22 % 5 = 2,所以在某种程度上先生成一个二进制长度为N的随机数,然后用同样的长度得到@987654369之间的随机值再次@结果,即范围0 to (N-1)。生成随机数的有点奇怪的方式,结合了随机的按位值生成和通过最终模数将其减少到更小的范围。

【讨论】:

    猜你喜欢
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多