2013-10-21 22 views
1

鑑於以下代碼 NSInteger random = arc4random_uniform(3) - 1;arc4random_uniform()和不同的行爲與arm64

此代碼編譯對ARMv7,ARMv7的和i386產生元件{的均勻分佈(在iPhone 5和iPhone模擬器測試)-1 ,0,1};但是當爲arm64編譯並在iPhone 5s上運行時,它會生成{4294967295,0,1}?

回答

3

arc4random_uniform返回一個unsigned int, - 1就可以將返回到最大的32位整數大小4294967295

你需要之前,你可以投arc4random_uniform(3)轉換成一個int -1它。 64位32位無符號/符號整數問題

規則4的

實施例:帶符號的值的總和和相同尺寸的無符號的值是一個無符號的值。

int a=-2; 
unsigned int b=1; 
long c = a + b; 
long long d=c; // to get a consistent size for printing. 

的printf( 「%LLD \ n」 個,d); 問題:在32位運行時中執行此代碼時,結果爲-1(0xffffffff)。當代碼在64位運行時運行時,結果爲4294967295(0x00000000ffffffff),這可能不是您所期望的。

原因:爲什麼會發生這種情況?首先,添加兩個數字。有符號值加無符號值會導致無符號值(規則4)。接下來,該值被提升爲更大的類型。此促銷不會導致符號擴展。

解決方案:要以32位兼容的方式解決此問題,請將b轉換爲長整型。此強制轉換強制在添加之前將b的非符號擴展提升強制爲64位類型,從而強制將帶符號整數提升(以簽名方式)以匹配。隨着這種變化,結果是預期的-1。

stolen from the apple 64-Bit Transition Guide.

+0

我同意,但是這並不能說明用,例如,它在模擬器上正常工作。 –

+0

模擬器使用不同的編譯器,編譯時arm64使用不同的指令集。我當然沒有資格詳細討論這個問題,但是看起來armv7和i386的編譯器是爲你自動渲染的,而arm64則不是。 –

+0

並且iPhone 5似乎也自動投射。我理解未簽名的問題,我想知道的是爲什麼這個「自動投射」正在發生或沒有。 –