2013-03-03 26 views
3

我想弄清楚一種方法,我可以隨機使用srand和rand生成-1,0或1。每當我做的,但是,我只能夠得到產生的範圍內的值,並從不-1或1隨機添加-1,0或1到C中的數字

這是我的嘗試:

int value; 
    srand(time(NULL)); 
    value=2*rand()/(RAND_MAX)-1; 

然而,在執行時,我總是生成0.我希望能夠偶爾生成-1和1。問題是我必須使用rand和srand作爲規範的一部分。任何幫助將不勝感激,並在此先感謝:)。

+1

記得調用'srand(time(NULL));'在你的程序中不要超過一次。特別是不要把它放在一個循環或一個被多次調用的函數中。 – pmg 2013-03-03 20:26:02

回答

8

如何

value = (rand() % 3) - 1; 

表達rand() % 3生成02(含)之間的隨機數,然後減去一個-11(含)之間得到。

+0

謝謝你幫助這個noob :)!我真的很感激它。 – russ0 2013-03-03 20:23:37

+4

當RAND_MAX%3不是2時,這種方法存在一個很小的偏差。當這是一個問題時,修復通常會在發生最後一個或兩個有問題的值(rand()可以採用時丟棄。 – 2013-03-03 20:35:27

+0

'2^n-1 mod 3'永遠不會是2,所以對於'RAND_MAX'的許多常見值將會存在偏差。 – harold 2013-03-03 20:42:15

0

你的代碼有一個錯誤的錯誤,並可能遭受整數溢出。

變化

value = 2 * rand()/RAND_MAX - 1; 

value = rand()/(RAND_MAX/3 + 1) - 1; 
+0

感謝您的迴應!我嘗試了第二個表達式,但每次都會生成1。 – russ0 2013-03-03 20:29:29

+0

@pmg:好點,我刪除了這句話。 – NPE 2013-03-03 20:29:38

2

首先,你要3個不同的值,但你只是要求2.第二,在一些實現(和顯然是一個你正在使用)RAND_MAX == INT_MAX,所以你的計算會受到溢出。您可以解決使用浮點

// srand(time(NULL)); Only do this once per invocation of your program 
int value = (int)(3.0*rand()/RAND_MAX) - 1; 

或long long

int value = 3LL*rand()/RAND_MAX - 1; 

或因子移動到除數:

int value = rand()/(RAND_MAX/3) - 1; 

編輯:請注意,這些都會產生稍微傾斜(或多或少,因爲RAND_MAX更少或更多)結果,因爲RAND_MAX不是3的倍數。您可以通過以下方式避免這種情況:

int r; 
do 
{ 
    r = rand(); 
} while (r >= RAND_MAX/3 * 3); 
int value = r/(RAND_MAX/3) - 1; 
+0

感謝您的回覆!出於某種原因,您的所有三條建議每次都會產生-1。我不確定這是爲什麼,因爲你的推理對我來說很合理。 – russ0 2013-03-03 21:21:52

+0

@ user2129657他們在這裏工作...... rand()返回什麼值,什麼是RAND_MAX?可能你的實現沒有正確定義RAND_MAX。 – 2013-03-04 00:23:53

+0

@JimBalter,+1試圖平均分配結果並顯示結果。 – 2013-03-04 01:24:34