【问题标题】:1 < -1 evaluates to TRUE1 < -1 评估为 TRUE
【发布时间】:2014-08-11 12:55:07
【问题描述】:

在我的部分代码中,我编写了一个简单的for 循环来迭代数组中的元素(全部为NSMutableDictionarys),我发现即使条件基本上是1

于是我写了如下代码,来测试这个问题的有效性:

NSMutableArray* arr = [[NSMutableArray alloc] init];

NSLog(@"COUNT: %d | %i", arr.count, 1 < (arr.count - 1));

输出是:

COUNT: 0 | 1

这本质上意味着计数为 0,并且 1 小于 -1。

我想也许是因为数组是新初始化的,也许添加和删除一个对象可能会改变这一点,所以我继续这样做:

NSMutableArray* arr = [[NSMutableArray alloc] init];

[arr addObject:@1];
[arr removeObject:@1];

NSLog(@"COUNT: %d | %i", arr.count, 1 < (arr.count - 1));

还是一样的结果:

COUNT: 0 | 1

我想到的可能原因:

  • 关于编译器/objective-C 的一些东西我还不明白
  • 我的 Mac 中的寄存器出没
  • 我疯了

我非常怀疑这是最后两种情况中的任何一种,但我仍然想知道为什么会发生这种情况。

【问题讨论】:

    标签: ios objective-c


    【解决方案1】:

    arr.count 是一个无符号整数值(NSUInteger 类型)。使用无符号算术,(0 - 1) 环绕到一个非常大的正数,而不是 -1

    如果将值转换为有符号整数,您可能会看到预期的结果:

    NSLog(@"COUNT: %d | %i", (int)arr.count, 1 < ((int)arr.count - 1));
    

    有关处理这种常见错误来源的一些方法,请参阅此主题:Constant bugs from [NSArray count] being unsigned

    【讨论】:

      【解决方案2】:

      出现这种情况的原因是左侧的1 被视为无符号。反过来,这是因为arr.count 是无符号类型,所以表达式arr.count-1 也是无符号的。当你从一个无符号零中减去1 时,你会得到一个下溢,结果是一个非常大的正数

      为避免此类问题,在处理 unsigned 类型的值时要格外小心减法。更喜欢加到对方——具体来说,而不是写

      if (a < unsignedB - c)
      

      if (a+c < unsignedB)
      

      【讨论】:

        【解决方案3】:

        数组的count属性是NSUInteger类型,表示unsigned long。表达式arr.count - 1 是从无符号整数中减去 1,因此结果也是无符号的。由于溢出,您得到的不是 -1,而是非常大的正数,而且这个数大于 1。

        【讨论】:

          【解决方案4】:

          [arr count] 返回 (NSUInteger) 这不过是 typedef unsigned long NSUInteger;

          所以NSUInteger 不会有任何负数。值从 0 开始到某个最大值,它就像一个循环,如下所示

          ... | MAX-2 | MAX-1 | MAX | 0 | 1 | 2 | 3 | 4 | ...
                     -1      -1    -1  -1  -1  -1  -1
          
          So, the math is like 2-1 = 1
                               1-1 = 0
                               0-1 = MAX
                               0-2 = MAX-1 
          

          【讨论】:

          • 我喜欢你的解释,但你所提供的信息是否正确?
          猜你喜欢
          • 1970-01-01
          • 2012-03-06
          • 1970-01-01
          • 2012-01-24
          • 1970-01-01
          • 2017-12-21
          • 2019-09-20
          • 2023-03-28
          相关资源
          最近更新 更多