为什么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多!
让我们来看看在你的两个例子中发生了什么。
-
从你的第一个例子,在这一行:
int rand = arc4random() % 100;
arc4random()
返回一个无符号的值。 那么它看起来像:int rand = someUnsignedNumber % 100;
100
是一个带符号的int,所以它被提升为与someUnsignedNumber
相同的types,并且应用%
操作。 之后你有:int rand = someUnsignedNumberBetween0And99;
将这个无符号数分配给
int rand
使其回到一个有符号数。 您的比较然后按预期前进。 -
在第二个例子中,你有这样的一行:
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之间进行的,因此不会执行此升级,因此将按照您的预期进行评估。