2012-10-12 70 views
0

我已經偶然發現了一個非常令人驚訝的問題,同時做一些隨機數的iOS的東西。在同一行代碼上生成兩個隨機數?

比較這些:

一)

int xOffsetSign = randomIntWithUpperLimit(2) ? 1:-1; 
int yOffsetSign = randomIntWithUpperLimit(2) ? 1:-1; 
int xOffset = randomIntWithUpperLimit(50) * xOffsetSign; 
int yOffset = randomIntWithUpperLimit(50) * yOffsetSign; 

B)

int xOffset = randomIntWithUpperLimit(50) * randomIntWithUpperLimit(2) ? 1:-1; 
int yOffset = randomIntWithUpperLimit(50) * randomIntWithUpperLimit(2) ? 1:-1; 

這是隨機函數:

static inline int randomIntWithUpperLimit(unsigned int upperLimit) { 
    return arc4random_uniform(upperLimit); 
} 

在我的腦海裏,無論a)和b)應該在th中產生隨機數e [-49,49]範圍。但是,只有a)有效。 b)僅產生[-1,1]範圍內的數字。

看起來,每個調用的第二個隨機部分首先被解析,被緩存,然後重新用於該行的第一部分,而不管上限。

有人可以解釋和澄清爲什麼b)不起作用嗎?

回答

1

這是一個優先問題。

int yOffset = randomIntWithUpperLimit(50) * randomIntWithUpperLimit(2) ? 1 : -1; 

相同

int yOffset = (randomIntWithUpperLimit(50) * randomIntWithUpperLimit(2)) ? 1 : -1; 

這是許多編碼標準需要大約?:結構括號這樣一個常見的問題。使用這個:

int yOffset = randomIntWithUpperLimit(50) * (randomIntWithUpperLimit(2) ? 1 : -1); 
+1

Doh!多麼愚蠢的錯誤。謝謝大家的答案。 –

0

這是關於運算符的關聯性和優先級。正在發生的事情是,你正在評估兩個你隨機數,然後-1和1之間選擇

您可能希望這樣的事情對於B:

int xOffset = randomIntWithUpperLimit(50) * (randomIntWithUpperLimit(2) ? 1:-1); 
int yOffset = randomIntWithUpperLimit(50) * (randomIntWithUpperLimit(2) ? 1:-1); 

這將確保你1和2之間選擇-1然後倍它由範圍爲0的隨機數爲49

-1

?:操作符的優先級較低然後*操作者

使用括號作爲此

randomIntWithUpperLimit(50) * (randomIntWithUpperLimit(2) ? 1:-1);