簡體   English   中英

rand()不返回隨機值

[英]rand() is not returning random values

它是一個生成隨機厄米特矩陣厄米特矩陣的小代碼。

我在每次調用rand()之前調用了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    

在main()中編輯調用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    

不要調用srand每次調用之前rand 程序啟動時調用一次。

如果循環,不要在內部調用srand 只打電話一次。

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

否則,您使用相同的種子為隨機生成器播種(因為它足夠快以獲得相同的時間)

BTW,很多次我覺得為程序/序列創建初始化函數是非常常規的,我初始化很多東西,包括隨機生成(例如調用srand()

您不希望每次都使用srand()為隨機數生成器播種! 只需在程序開頭調用一次即可。 然后調用rand()獲取下一個隨機數。

不要這樣做:

rand()%RAND_RANGE + 0*I;

,因為如果RAND_RANGE和RAND_MAX + 1不分頻,它將導致較低的值被過采樣。 (“幾乎總是”就是這種情況)

另外:基於時間(NULL)重新啟動生成器在大多數情況下將以完全相同的值重新啟動,因為time_t的粒度是一秒。

最終:rand_max將至少有 15位(32K)的隨機值。 較舊的系統實際上可能只提供15位,周期為32 K.

更新:這是來自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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM