✔ 最佳答案
假設您的 random() 函數會產生至少 8 種的均勻亂數值,假設範圍在 0~10000 之間的整數,那麼
B=random()%8;
表示 B 為 0~10000 之間的任意數值除以 8 後所得的餘數。所以囉,任意數字除以 8 取餘數就只會有 8 種,分別是 0、1、2、3、4、5、6 與 7。
假設您的時間戳記 now 的單位為秒,並且是從 1970/01/01 00:00:00'GMT 開始計算(也就是從 1970/1/1 00:00:00 開始到現在已經過了多少秒),那麼在 1991/07/02 15:00:00 開始,for 迴圈就失效了,也就是 for 迴圈中的 random(); 不再執行。
程式語言所提供的亂數,多數會以亂數種子為依據,產生第一個亂數值,而後的亂數值依據上一個亂數值產生。根據您的程式:
srandom(33);
/*接下來這行在 1991/07/02 15:00:00 後就不會執行了*/
/*1991/07/02 15:00:00 時間戳記為 678466800*/
/*678466800/(60*60*3)=62821,62821-62820=1>0,致使迴圈失效*/
for(n=(now/(60*60*3))- 62820; n >0; n--) random();
B=random()%8;
也就是變成以下等效的程式:
srandom(33);
B=random()%8;
如果每次 B 的亂數值都是由亂數種子 33 決定,那麼不用說五小時,而是每次取得的亂數值都一樣,並且是落在 0~7 之間(各種語言工具所提供的亂數產生方式不一,所得到的結果與您所使用編譯器的不同而有所不同)。
2007-05-25 05:13:53 補充:
至於如何預測,假設您的 random() 的尺度為 32 bits,也就是 2 的 32 次方種,依據程式語言所提供的亂數方式(下一次的亂數值取決於這一次的亂數值),淡藍色認為從位元排列方式的觀點,統計 2 的 32 次方加 1 次的亂數序列,必定至少會有一次循環序列發生,接著依據循環序列求算 random() 產生亂數的數學規則。
2007-06-01 13:11:26 補充:
unsigned long int next = 1; /*這個用來當作亂數種子*/
/* srandom: set seed for random() */
void srandom(unsigned int seed)
{
next = seed; /*設定亂數種子*/
}
2007-06-01 13:12:53 補充:
/* random:return pseudo-random integer on 0...32767 */
int random(void)
{
/* 將亂數種子做很大的數學變化,例如乘上很大的數或者加上很大的數,淡藍色認為這些數字以巨大的質數為最好。 */
next = next * 1103515245 + 12345;
/* 這裡用來限定回傳的範圍 */
return (unsigned int) (next/65536) % 32768;
}
2007-06-01 13:38:51 補充:
仔細觀察 random() 回傳的亂數值根據 next 決定,而 srandom() 函數直接決定 next 為何,也就是只要 next 固定成一個值(您的例子為 33),則 random() 回傳的亂數值就會固定是某一個值。這是假設作法,各家編譯器編譯所編譯的程式,透過固定的亂數種子所產生的那個固定亂數值都有所不同。
2007-06-01 13:39:20 補充:
至於您提到的 BBS 是指電子佈告欄(Bulletin Board System)吧?它是一種網路相關的應用程式,應該不限定什麼工具語言製作,但是淡藍色認為會以 C 語言工具製作為多。