为什么arc4random()在将variables存储在variables中时performance不同?

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"); } 

在这里,我不是把它存储在一个variables中,而是直接在条件中放置了随机数expression式。 条件满足 (有时)。

这是为什么? 我怎样才能debugging这种行为?

键入促销规则。

arc4random返回一个无符号的值。 这意味着在你的第二种情况下, -5被升级到同样的无符号types,把它变成4294967291 。 40亿以上肯定比0-99多!

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

  1. 从你的第一个例子,在这一行:

     int rand = arc4random() % 100; 

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

     int rand = someUnsignedNumber % 100; 

    100是一个带符号的int,所以它被提升为与someUnsignedNumber相同的types,并且应用%操作。 之后你有:

     int rand = someUnsignedNumberBetween0And99; 

    将这个无符号数分配给int rand使其回到一个有符号数。 您的比较然后按预期前进。

  2. 在第二个例子中,你有这样的一行:

     if (arc4random() % 100 <= chance) 

    arc4random() % 100发生同样的情况,产生如下的结果:

     if (someUnsignedNumberBetween0And99 <= chance) 

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

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

 u_int32_t arc4random(void); 

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

当比较其无符号结果与另一个整数时,无符号“胜”:另一个值( -5 )被提升为无符号types(在这种情况下为u_int32_t ),它会翻转(因为无符号整数“underflow”被devise为在C中这样工作 – 你会得到2 ^ 32 - 5 ),所以出现了一个“错误的”(即,意外行为)的比较。

当您明确地将该值分配给一个int (即signed )variables时,由于比较是在两个签名types之间进行的,因此不会执行此升级,因此将按照您的预期进行评估。