2009-08-31 70 views
6

我想隨機生成一個正數或負數,而不用擔心更大的範圍,我希望隨機生成1或-1,然後乘以我的​​另一個隨機數數。Objective C - 隨機結果是1或-1

我知道這可以通過生成0或1的較長規則來完成,然後檢查返回並使用它乘以1或-1。

希望有人知道一個更簡單的方法來隨機設置一個數字上的標誌。儘量保持我的代碼儘可能乾淨。

回答

22

我喜歡用arc4random()因爲它不要求你種子隨機數發生器。它還方便地返回一個uint_32_t,所以你不必擔心0和1之間的結果等,它只會給你一個隨機整數。

int myRandom() { 
    return (arc4random() % 2 ? 1 : -1); 
} 
+0

+1簡單明瞭。 – 2009-09-01 04:26:42

+0

非常聰明,謝謝! – kubilay 2014-04-22 06:10:33

10

如果我理解正確的問題,你想要的1和-1的僞隨機序列:

int f(void) 
{ 
     return random() & 1 ? 1 : -1; 
    // or... 
    // return 2 * (random() & 1) - 1; 
    // or... 
    // return ((random() & 1) << 1) - 1; 
    // or... 
    // return (random() & 2) - 1; // This one from Chris Lutz 
} 

更新:好的,事情一直困擾着我,因爲我寫了這一點。常見的RNG頻繁的弱點之一是低階比特可以經歷短週期。這也可能是最好的測試高階位:    random() & 0x80000 ? 1 : -1

+5

爲什麼不'(隨機()2) - 1'? – 2009-08-31 22:31:43

+2

只是提醒那些不熟悉由確定性系統生成的隨機數的人 - 他們並不是真正的隨機數。你可能想調用'srandomdev();'在一些方便的「應用程序啓動」點。你只需要調用一次。這爲隨機數發生器生成了合理隨機位的來源,所以random()的結果是「更隨機的」。否則,'random()'每次以完全相同的種子開始。 – johne 2009-09-01 00:15:01

+0

假設我們正在討論'Xcode.app' /您的標準Cocoa應用程序,調用'srandom()'的最明顯的地方在'Xcode.app'提供的main.m文件中, 'main()'函數,就在調用'NSApplicationMain()'之前。 – johne 2009-09-01 03:03:47

0

要產生1或-1直接,你可以這樣做:

int PlusOrMinusOne() { 
    return (rand() % 2) * 2 - 1 
} 

可你爲什麼擔心更廣泛的範圍內?

+0

rand()有一些問題。也許應該考慮使用別的東西。 http://ianbullard.squarespace.com/journal/2009/4/28/why-you-should-never-use-rand.html – neoneye 2009-08-31 22:11:54

-1

這個額外的步驟不會給你任何額外的「隨機性」。只需在您需要的範圍內直接生成您的號碼(例如-10..10)。 標準rand()將從此範圍返回一個值:0..1 您可以將其乘以常數以增加範圍的範圍,或者可以添加常數以在X軸上向左/向右推動該範圍。 例如以從(-5..10)生成隨機值的範圍,你將有: 蘭特()* 15-5

+0

@johne - 我認爲德米特里讓Java與ObjectiveC混淆...... – 2009-09-01 13:52:49

+0

抱歉混亂。我沒有特別指出任何語言,而是一個從0..1範圍內返回隨機(浮點)值的泛型函數。我的主要焦點是解釋如何將其轉換爲任何其他範圍(即,您不需要生成-1或1個隨機值) – DmitryK 2009-09-01 22:10:39

-1

rand會給你從0到RAND_MAX的數,這將覆蓋所有的位在除了一個int標誌。通過將該結果左移1位,可以將帶符號的MSB變爲符號,但將位清零,您可以使用從rand的另一個調用的隨機位重新填充該位。該代碼將看起來像:

int my_rand() 
{ 
    return (rand() << 1) + (rand() & 1); 
} 
+1

-1用於使用不必要的複雜C++過度簡化Objective-C問題。通常我不會在乎這些問題,但C標準庫具有非常好的隨機數函數,不需要使用C++,這可能會產生一些相當令人討厭的副作用,並使編譯,運行時等複雜化。 – 2009-09-01 04:31:00

+0

我拿出std ::命名空間,所以它現在是有效的C.'std :: rand'與C使用的'rand'相同,只是保護在'std'命名空間後面以避免衝突。 – fbrereto 2009-09-01 04:36:15

0
return (((arc4random() & 2) * 2) - 1);