NSUInteger 的 “负值” 问题

作者: StoneN | 来源:发表于2017-08-07 22:19 被阅读100次
    说明:

    今天遇到一个特别的Bug

    NSArray *array;
    // 定义 array 为:存有 100 个数的数组;
    NSInteger index = -1;
    if (index >= array.count) {
      NSLog(@"index >= 100");
    } else {
      NSLog(@"index < 100");
    }
    // 打印:index >= 100
    

    显然,结果和我们期待的很不一样:难道不应该是-1 < 100吗?经过一番查证,终于找到了问题所在,特此以记之。

    问题详述:
    • NSArray.count的类型为NSUInteger.
      // NSArray.h 中 count 属性如下:
      @property (readonly) NSUInteger count;
      
    • 若给NSUInteger型变量赋值为-1,它将被自动转换成NSUInteger的最大值,且自-1向下一一对应.
      NSUInteger a = 0;
      a = 2;    NSLog(@" a=2 === %lu",(unsigned long)a);
      a = 1;    NSLog(@" a=1 === %lu",(unsigned long)a);
      a = 0;    NSLog(@" a=0 === %lu",(unsigned long)a);
      NSLog(@"");
      a = -1;   NSLog(@"a=-1 === %lu",(unsigned long)a);
      a = -2;   NSLog(@"a=-2 === %lu",(unsigned long)a);
      a = -3;   NSLog(@"a=-3 === %lu",(unsigned long)a);
      a = -4;   NSLog(@"a=-4 === %lu",(unsigned long)a);
      a = -5;   NSLog(@"a=-5 === %lu",(unsigned long)a);
      NSLog(@"");
      a = -1;
      a = a - 18446744073709551615; 
      //编译器警告18446744073709551615太大不能放进NSInteger,会自动转换为NSUInteger
      NSLog(@"a(= -1) - 18446744073709551615 = %lu",(unsigned long)a);
      
      // 打印结果如下:
      //  a=2 === 2
      //  a=1 === 1
      //  a=0 === 0
      // 
      //  a=-1 === 18446744073709551615
      //  a=-2 === 18446744073709551614
      //  a=-3 === 18446744073709551613
      //  a=-4 === 18446744073709551612
      //  a=-5 === 18446744073709551611
      //  
      //  a(=-1) - 18446744073709551615 === 0
      
    • NSIntegerNSUInteger进行运算时,编译器会自动将NSInteger转换成对应的NSUInteger,这便是造成文章开头所提出的,产生与直觉相悖结果的原因.
      NSInteger b = -1;
      NSUInteger ub = 0;      
      if (b > ub) {          
          NSLog(@"-1 > 0");
      } else {
          NSLog(@"-1 < 0");
      }
      // 打印:-1 > 0 
      
    解决方法:

    若必要,在拿NSIntegerNSUInteger进行运算时,需手动将NSUInteger转型为NSInteger.

    NSInteger b = -1;
    NSUInteger ub = 0;     
    if (b > (NSInteger)ub) {          
        NSLog(@"-1 > 0");
    } else {
        NSLog(@"-1 < 0");
    }
    // 打印:-1 < 0 
    

    相关文章

      网友评论

        本文标题:NSUInteger 的 “负值” 问题

        本文链接:https://www.haomeiwen.com/subject/evjalxtx.html