3
    int chance = -5;
    int rand = arc4random() % 100;   // Number from 0 to 99
    if (rand <= chance) {            // This will never happen
        NSLog(@"This is... NOT POSSIBLE");
    }

实际上,这永远不会发生。但

    int chance = -5;
    if (arc4random() % 100 <= chance) {
        NSLog(@"This is... NOT POSSIBLE");
    }

在这里,我没有将它存储在变量中,而是将随机数表达式直接放在条件中。并且条件得到满足(有时)。

这是为什么?如何调试此行为?

4

2 回答 2

6

键入促销规则。

arc4random返回一个无符号值。这意味着在您的第二种情况下,-5被提升为相同的无符号类型,将其转换为4294967291. 4+十亿绝对比任何数字0-99都要大!

让我们来看看你的两个例子中发生了什么。

  1. 从您的第一个示例中,在这一行中:

    int rand = arc4random() % 100;
    

    arc4random()返回一个无符号值。那么它看起来像:

    int rand = someUnsignedNumber % 100;
    

    100一个有符号整数,因此它被提升为与 相同的类型someUnsignedNumber,并应用该%操作。之后你有:

    int rand = someUnsignedNumberBetween0And99;
    

    分配那个无符号的数字,int rand使它回到一个有符号的数字。然后,您的比较会按预期进行。

  2. 在第二个示例中,您有这一行:

    if (arc4random() % 100 <= chance)
    

    发生同样的事情arc4random() % 100,产生类似:

    if (someUnsignedNumberBetween0And99 <= chance)
    

    但在这里,chance是一个签名号码。它被提升,如上所述改变它的价值,你最终会看到你所看到的奇怪行为。

于 2013-02-27T18:59:47.800 回答
5

C 的愚蠢,愚蠢的类型系统...如果您阅读手册页arc4random()您会发现它的原型是

u_int32_t arc4random(void);

所以它返回一个无符号整数。

当将其 - 无符号 - 结果与另一个整数进行比较时,无符号“获胜”:另一个值 ( -5) 被提升为无符号类型(u_int32_t在这种情况下),它翻转(因为无符号整数“下溢”旨在像这样工作在 C 中 - 你会得到2 ^ 32 - 5) ,因此会发生“错误”(即行为出乎意料)比较。

当您将值显式分配给int(即有符号的)变量时,不会发生这种提升,因为比较是在两个有符号类型之间进行的,因此它会按照您的预期进行评估。

于 2013-02-27T19:02:00.837 回答