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
所以,就有了开头的那个结果。

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