【问题标题】:count number using random number rand()使用随机数 rand() 计数
【发布时间】:2011-03-31 18:31:41
【问题描述】:

我正在学习C,发现rand()很奇怪,可能是因为它的随机性:p

我有下面的代码,它总是输出1,有什么问题吗?您将如何修改代码以使其完成工作?

干杯,

#include <stdlib.h>

double rand_double()
{
    double ret = (double)rand();
    return ret/(RAND_MAX+1);
}

int sample_geometric_rv(double p)
{
    double q;
    int n = 0;
    do
    {
        q = rand_double();
        n++;
    } while (q >= p);
    return n;
}

int main()
{
    int ans = sample_geometric_rv(0.1);
    printf("Output %d\n", ans);
    return 0;
}

【问题讨论】:

    标签: c random


    【解决方案1】:

    您需要为随机数生成器播种ONCE。每次您需要不同的序列时,请使用具有不同值的 srand()

    在没有播种的情况下,就好像你发了srand(1);

    通常,RNG 以当前时间作为初始化值在main() 中播种。 time() 返回的当前时间几乎可以保证在程序的每次运行中都不同(每秒更改一次)。

    #include <stdlib.h>
    #include <time.h>
    
    int main(void) {
        srand(time(0));
        /* rest of program; no more calls to srand() */
        return 0;
    }
    

    请注意,如果您使用相同的编号初始化 RNG,您将获得相同的序列。这可能很有趣,例如,重复数据。

    还要注意,在不同的计算机上,相同的初始化编号不需要生成相同的编号。

    【讨论】:

    • 记住一个重点:每个程序只有一个srand()调用。
    【解决方案2】:

    这里的RAND_MAX很可能是(2^31)-1(最大32位有符号整数),所以加1会导致它回绕变成负数,这反过来意味着对于p的任何正值p都会超过q .改变这个:

     return ret/(RAND_MAX+1);
    

    到这里:

     return ret/((double)RAND_MAX+1.0);
    

    也强烈建议播种 RNG(如前所述)。

    【讨论】:

    • 您是说不需要强制转换,因为1.0 将导致整个语句被评估为double?强制转换允许除数增加超出其默认数据类型的限制。
    • 是的。如果没有演员表,你有 int+double 并且 int 将在添加之前隐式转换为 double ;使用强制转换(显式转换),您有 double+double 并且没有隐式转换。但是演员阵容很丑陋,很少需要。
    • 我同意丑陋的一点。我不记得评估将采用哪种方式(并且实际上遇到了将 int+double 评估为 int 的编译器)所以我认为我会很安全。
    • 6.3.1.8 Usual arithmetic conversions6.5.6 Additive operators 涵盖了表达式 RAND_MAX + 1.0 中使用的转换 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 2015-09-29
    • 2023-03-19
    相关资源
    最近更新 更多