[英]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.