rand() is not returning random values

陌路散爱 提交于 2019-12-08 02:02:04

问题


Its a small code to generate a random hermitian matrix hermitian matrix.

I have called srand() before every call to rand(). but still no randomness in the output.

I have used c99's complex datatype feature to create a hermitian matrix. I'm not sure where i'm wrong :(

#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;
}

sample output

[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    

EDIT calling srand in main() actually solved the problem. Thank you guys.

[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    

回答1:


Don't call srand before every call to rand. Call it once when your program starts.




回答2:


Don't call srand inside if the loop. Call it only once.

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

Otherwise you seed the random generator with the same seed (as it is fast enough to get the same time)

BTW, many times I find it very conventional to create an init function for the program / sequence where I initialize many things, including the random generation (e.g. call srand())




回答3:


You don't want to seed the random number generator with srand() every time! Just call it once at the beginning of your program. Then call rand() to get the next random number.




回答4:


Don't do this:

rand()%RAND_RANGE + 0*I;

, since it will cause the lower values to be oversampled if RAND_RANGE and RAND_MAX+1 don't divide. (which "almost always" is the case)

Also: restarting the generator based on time(NULL) will in most cases restart with exactly the same value, since the granularity of time_t is one second.

Final: rand_max will have at least 15 bits (32K) worth of random. Older systems might actually deliver only 15 bits, with a cycle of 32 K.

UPDATE: this is a snippet from wakkerbot. The urnd() function attempts to return an unbiased value between 0 and range. The test can probably be performed more elegantly.

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
}


来源:https://stackoverflow.com/questions/10259028/rand-is-not-returning-random-values

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!