【问题标题】:Why isn't this number random?为什么这个数字不是随机的?
【发布时间】:2011-04-30 13:01:58
【问题描述】:

对于下面的一段代码:

#include<stdlib.h>
#include<stdio.h>

int main()
{
    int x;
    x = rand()%100;
    printf("The Random Number is: %i", x);

return 0;
}

它似乎总是将随机数打印为 83。这是为什么呢?

【问题讨论】:

  • 因为你没有初始化 PRNG。您需要根据时间等变化来设置种子。但我建议完全避免集成 c PRNG。
  • @CodeInChaos:什么是“PRNG”?您在这里与一个完整的 C n00b 交谈。
  • 我只想重申,rand 的大多数实现都非常糟糕,即使在简单的模拟中也会崩溃。

标签: c random


【解决方案1】:

大多数random number generators 都是可重复的。您需要在使用之前播种生成器,这通常使用系统时间。

#include <time.h>
srand(time(NULL));

【讨论】:

  • 请注意,从那时起初始化 PRNG 并不总是可以的:这为您提供了可预测的种子。特别是,密码学需要不可预测的随机数,但 C 库无论如何都不会提供。
  • 请注意,仅使用时间往往会在高线程系统(如 Web 服务器)上惨遭失败,其中两个不同的线程可能同时运行(在 time() 的精度范围内)。跨度>
【解决方案2】:

强制性 XKCD 参考:

正如人们所说,您需要正确地播种 pseudo 随机数生成器。

问题是,它仍然只生成个随机数。大多数“真实”随机数生成器都需要访问 random in nature 的某些物理现象(例如,时钟偏差或温度波动)。

否则,XKCD 参考与事实相差不远。呆伯特也不是。

【讨论】:

  • 谢谢,我喜欢流行文化参考!
  • @jones:不客气!一旦你开始研究它们,随机数就是一个滑坡。 xkcd 和 Dilbert 漫画显然知道这一点,并很早就在沙子上画了一条线。 :-)
  • @downvoter:为什么?在没有解释的情况下投票是 --- 充其量是 --- 粗鲁,或者,在我看来,是懦弱的。据我所知,我的帖子中没有任何内容不诚实或不回答问题 (stackoverflow.com/faq)。
【解决方案3】:

因为 rand 使用的伪随机数生成器始终使用相同的种子进行初始化。

要使用不同的种子对其进行初始化,您可以使用 srand 函数,并将其初始化为 srand(time(NULL))

【讨论】:

    【解决方案4】:

    因为 83 是一个随机数,不是吗?

    更严重的是,让程序提供可重复的行为很有用,因此默认情况下,如果您不更改种子,rand 总是返回相同的数字序列。

    【讨论】:

    • +1 是您总是想要随机随机数的一个很好的理由!
    【解决方案5】:

    通过包含&lt;time.h&gt; 和调用srand(time(0)); 来播种随机数生成器(感谢我的评论者编辑)

    【讨论】:

    • @R。时间的类型为 time_t。我不相信它一定是一个无符号整数,尽管它通常是。
    • @jonsca: time_t 保证是算术类型,所以无论如何它都会被转换为正确的类型。 (如果 time_t 被允许是别的东西,演员表就不起作用了,所以不管怎样都是没用的。)
    • @Gilles 我以前总是收到警告,但由于某种原因它们没有弹出。我得调查一下。感谢您发表实际声明。
    • @jonsca:C 中强制转换的经验法则:如果您收到编译器警告并且添加强制转换会使警告静音,那么您正在修复症状并保留问题。在大多数需要强制转换的情况下,编译器不够聪明,无法警告您。
    • 原则上这可能是未定义的行为,无论是否有强制转换,因为time_t 允许为浮点类型,并且当前时间的值可能太大而无法放入unsigned int。正如 Gilles 所说,任何来自编译器的被强制转换抑制的警告实际上可能会告诉您一些理论上重要的事情,例如您的代码将在某个截止日期停止工作。诚然,对于 Unix epoc 和 32 位 int,截止日期是 2106 年,所以可能没有太大的实际意义......
    【解决方案6】:

    您无法生成真正随机的随机数,除非您的随机数生成器能够访问 peter 之前引用的真正随机的物理现象。但是对于一般用途,您可以使用 C 的标准库函数来生成随机数。下面是在两个限制(最大值和最小值)之间生成随机数的示例代码:

    #include<stdio.h>
    #include<stdlib.h>
    
    #define MIN 1
    #define MAX 5
    #define QUANTITY 5
    
    int main()
    {
         int i;
         //stores the time in seconds
         time_t seconds;
         //getting the system time
         time(&seconds);
         //initializing the random generator with system time
         //as the seed value
         srand((long)seconds);
    
         for(i = 0; i < QUANTITY; i++)
         {
               printf("%f\t",((float)rand())/RAND_MAX*(MAX-MIN)+MIN);
         }
         printf("\n");
    
         return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-05-21
      • 2014-02-02
      • 1970-01-01
      • 1970-01-01
      • 2018-10-25
      • 2014-11-17
      • 1970-01-01
      • 2023-03-11
      • 2023-03-30
      相关资源
      最近更新 更多