C编程 - 来自rand()的奇怪输出

时间:2011-09-14 22:51:51

标签: c random srand

下面是我练习使用rand()函数的示例程序。

最奇怪的是每次运行程序时,rand()(程序输出中的rand [0])生成的第一个数字是SIMILAR。它不一样,但数字总是略大于上次生成的数字。 rand [1-4]似乎是可接受的随机。任何人都可以解释发生了什么,为什么?

看看这个示例输出:

[paul@experimental C] $ ./a.out
rand[0]= 277735441                  <<<??????
rand[1]= 1417591956
rand[2]= 1284424674
rand[3]= 819876274
rand[4]= 1405457966
[paul@experimental C] $ ./a.out
rand[0]= 277769055                  <<<???????
rand[1]= 1982542454
rand[2]= 234757526
rand[3]= 642279943
rand[4]= 1546192179
[paul@experimental C] $ ./a.out
rand[0]= 277785862                  <<<??????? 
rand[1]= 117534056
rand[2]= 1857407599
rand[3]= 1627223601
rand[4]= 542817462

源代码:

 /*
     * rand: Generates 5 numbers using standard "srand()/rand()" function
     *
     * SAMPLE OUTPUT:
     *   rand[0]= 824522256
     *   rand[1]= 1360907941
     *   rand[2]= 1513675795
     *   rand[3]= 1046462087
     *   rand[4]= 253823980
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>

    int
    main (int argc, char *argv[])
    {
      /* Simple "srand()" seed: just use "time()" */
      unsigned int iseed = (unsigned int)time(0);
      srand (iseed);

      /* Now generate 5 pseudo-random numbers */
      int i;
      for (i=0; i<5; i++)
      {
        printf ("rand[%d]= %u\n",
          i, rand ());
      }
      return 0;
    }

4 个答案:

答案 0 :(得分:4)

srand的常见实现使第一个随机数与其种子高度相关。该标准不保证序列的随机性。

答案 1 :(得分:0)

rand返回一个signed int。您将其打印为无符号值。

答案 2 :(得分:0)

基本上rand()是一个伪随机生成器。由于您使用时间()播种,这可能是数字相似的原因。

尝试使用gettimeofday()乘以tv_sec * tv_usec或类似的东西播种。

答案 3 :(得分:0)

伪随机生成器绝不是真正随机的,而是基于各种各样的数学算法。在我的系统上,根据手册页显然使用了一个相当简单的系统:

static unsigned long next = 1;

    /* RAND_MAX assumed to be 32767 */
    int myrand(void) {
    next = next * 1103515245 + 12345;
        return((unsigned)(next/65536) % 32768);
    }

    void mysrand(unsigned seed) {
        next = seed;
    }

这些类型的随机发生器已经存在了一段时间。如果你熟悉余数算术,那么你会看到你取一个起始值,然后用相对于32768的余数扭转并转动它,所以得到一个你机器承诺的范围内的值。关于这一点,没有什么是随机的。然后,您生成的值将用作下一个数字的起始值。

在您的情况下,您使用当前时间播种。如果你运行你的程序足够快,你甚至可能得到相同的值(这不应该发生,但是当我编译你的小程序并在我的系统上运行它时,它对我有用)。在任何情况下,如果你有一个快速运行,你可能会看到类似的值 - 直到你'翻转'剩余基数。

也许在这里阅读随机数生成:

http://en.wikipedia.org/wiki/Pseudorandom_number_generator

它会更有意义。

编辑:如果你想知道人们如何提出用于乘以种子值的常数,那么伪随机生成器的质量将根据许多标准进行评估,例如,结果值是“随机查找”或'聚集'。如果你需要非常好的伪随机数(可能现在不是),你可能想要实现自己的伪随机数。