兰特()没有返回随机值(rand() is not returning random values)

2019-09-16 16:15发布

它是一个小的代码生成随机Hermitian矩阵埃尔米特矩阵 。

我每次调用兰特以前也称为函数srand()()。 但仍然在输出中没有随机性。

我已经使用C99的复杂数据类型功能来创建一个埃尔米特矩阵。 我不知道在那里我错了:(

#include <stdio.h>
#include <math.h>
#include <complex.h>
#include <stdlib.h>
#include <time.h>

#define MATSIZE 5
#define RAND_RANGE 100

double complex mat[MATSIZE][MATSIZE];

void gen_mat()
{
  int i =0,j;
  int real;
  int img;
  for( ;i < MATSIZE; i++)
  {
    srand(time(NULL));
    real = rand()%RAND_RANGE + 1;
    srand(time(NULL));
    img = rand()%RAND_RANGE + 1;
    for(j = MATSIZE; j != i ; j--) 
    { 
       mat[i][j] = real + img * I;
       mat[j][i] = conj(mat[i][j]);
    }
    srand(time(NULL));
    if(i == j)
      mat[i][i] = rand()%RAND_RANGE + 0*I;
  }
}

void print_mat()
{
  int i,j;
  for(i = 0; i < MATSIZE; i++)
  {
    for(j = 0; j < MATSIZE; j++)
    {
      printf("%f + %f *i", creal(mat[i][j]), cimag(mat[i][j]));
      printf("    ");
    }
    puts("\n");
  }
}

int main()
{
  gen_mat();
  print_mat();
  return 0;
}

样本输出

[aft@centos-c physics-numaric]$ ./a.out 
66.000000 + 0.000000 *i    67.000000 + 67.000000 *i    67.000000 + 67.000000 *i             67.000000 + 67.000000 *i    67.000000 + 67.000000 *i    

67.000000 + -67.000000 *i    66.000000 + 0.000000 *i    67.000000 + 67.000000 *i      67.000000 + 67.000000 *i    67.000000 + 67.000000 *i    

67.000000 + 67.000000 *i    67.000000 + -67.000000 *i    66.000000 + 0.000000 *i    67.000000 + 67.000000 *i    67.000000 + 67.000000 *i    

67.000000 + 67.000000 *i    67.000000 + -67.000000 *i    67.000000 + -67.000000 *i    66.000000 + 0.000000 *i    67.000000 + 67.000000 *i    

67.000000 + 67.000000 *i    67.000000 + -67.000000 *i    67.000000 + -67.000000 *i      67.000000 + -67.000000 *i    66.000000 + 0.000000 *i    

编辑调用主srand()函数实际上解决了这个问题。 感谢大伙们。

[aft@centos-c physics-numaric]$ ./a.out 
31.000000 + 0.000000 *i    81.000000 + 75.000000 *i    81.000000 + 75.000000 *i     81.000000 + 75.000000 *i    81.000000 + 75.000000 *i    

81.000000 + -75.000000 *i    53.000000 + 0.000000 *i    69.000000 + 57.000000 *i    69.000000 + 57.000000 *i    69.000000 + 57.000000 *i    

69.000000 + 57.000000 *i    69.000000 + -57.000000 *i    27.000000 + 0.000000 *i    93.000000 + 11.000000 *i    93.000000 + 11.000000 *i    

93.000000 + 11.000000 *i    69.000000 + -57.000000 *i    93.000000 + -11.000000 *i    58.000000 + 0.000000 *i    76.000000 + 78.000000 *i    

76.000000 + 78.000000 *i    69.000000 + -57.000000 *i    93.000000 + -11.000000 *i    76.000000 + -78.000000 *i    67.000000 + 0.000000 *i    

Answer 1:

不要调用srand每次调用之前rand 。 你的程序启动时调用一次。



Answer 2:

不要调用srand内如果循环。 说它只有一次。

srand(time(NULL));
for( ;i < MATSIZE; i++)
{
    // ... calls to rand()   
}

否则,你的种子使用相同的种子随机数发生器(因为它是足够快,以获得相同的时间)

顺便说一句,很多时候我觉得很传统的以创建程序/序列,其中我初始化很多事情,包括随机生成一个初始化函数(例如调用srand()



Answer 3:

你不想种子与随机数发生器srand()每一次! 只需在程序开始调用它一次。 然后调用rand()来获得一个随机数。



Answer 4:

不这样做:

rand()%RAND_RANGE + 0*I;

的,因为它会导致较低的值被过采样,如果RAND_RANGE和RAND_MAX + 1不分裂。 (其中“几乎总是”是的情况下)

另外:重新启动基于时间(NULL)在大多数情况下具有完全相同的值来重新启动发电机,因为time_t的粒度为1秒。

决赛:RAND_MAX会随机至少 15位(32K)的价值。 旧的系统实际上可能只提供15位,32 K的周期

UPDATE:这是从一个片段wakkerbot 。 所述urnd()函数尝试0和范围之间返回一个无偏值。 该测试大概可以进行更优雅。

typedef unsigned long long BigThing;

unsigned int urnd(unsigned int range)
{
    static bool flag = FALSE;

    if (flag == FALSE) {
#if defined(__mac_os) || defined(DOS)
        srand(time(NULL));
#else
        srand48(time(NULL));
#endif
    }
    flag = TRUE;
#if defined(__mac_os) || defined(DOS)
    return rand()%range;
#else

if (range <= 1) return 0;

while(1)        {
    BigThing val, box;
#if WANT_RDTSC_RANDOM
    val = rdtsc_rand();
#else
    val =  lrand48();
#endif
/* we need this to avoid oversampling of the lower values.
 * Oversampling the lower values becomes more of a problem if (UNSIGNED_MAX/range) gets smaller
 */
    box = val / range;
    if ((1+box) *range < range) continue;
    return val % range;
        }
#endif
}


文章来源: rand() is not returning random values