iOS小知識(四)-從NSUInteger談起 答案是:

我們先看一組簡單的代碼,猜一猜控制檯會輸出什麼呢?
    NSInteger a = -1;
    NSArray *array = @[@"str"];
    if (a > array.count) {
        NSLog(@"測試1");
    }else{
        NSLog(@"測試2");
    }

答案是:

控制檯爲輸出 “測試1”,也就是說if裏面的判斷,-1>1是成立的,這明顯是反常識的,爲什麼if條件會成立的,我們繼續往下看。


在CPU爲64位情況下(iPhone5s及以後的機型,均爲64位)
NSInteger即爲long類型 64位下
NSUInteger 即爲 unsigned long 類型
64位下,long和unsigned long下所佔字節均爲8字節。
首先變量a是NSInteger類型,而NSArray的count屬性,我們點進去去看,可以看到是NSUInteger類型(NSString的length類型同爲NSUInteger),所以if裏面的表達式本質就成爲了long 和 unsigned long 進行數值比較。即有符號和無符號數的比較。
而編譯器在判斷有符號數和無符號數進行比較時,一律會將有符號數轉化爲無符號數。即將NSInteger類型的值-1轉換爲NSUInteger類型

那麼,有符號數如何轉化爲無符號數呢?

在計算機內存存儲的有符號數的最高位變爲數據位,即有符號數轉爲無符號數。

在計算機中,數據是以補碼的形式存在的。

原碼:正數的原碼是自己
補碼:除符號位外,按位取反,然後+1
所以十進制的-1轉成8個字節64位二進制後,爲
1000 0000 0000 ... 0001 (共64位,首位爲符號位1 表示爲負數)
而實際上計算機存儲的-1是它的補碼 即:
1111 1111 1111 ... 1111
轉成無符號數後,最高位的1不在表示符號位,而表示數據位。
64個1 即(2的64次方-1)
結果是
18446744073709551615
所以if裏面的表達式-1 在轉爲無符號數以後,最後變成了:18446744073709551615
所以,就有了開頭的那個結果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章