int chance = -5;
int rand = arc4random() % 100; // Number from 0 to 99
if (rand <= chance) { // This will never happen
NSLog(@"This is... NOT POSSIBLE");
}
Run Code Online (Sandbox Code Playgroud)
实际上,这种情况从未发生过.但
int chance = -5;
if (arc4random() % 100 <= chance) {
NSLog(@"This is... NOT POSSIBLE");
}
Run Code Online (Sandbox Code Playgroud)
这里,我将随机数表达式直接放在条件中,而不是将其存储在变量中.并且条件得以实现(有时).
这是为什么?我该如何调试此行为?
输入促销规则.
arc4random返回无符号值.这意味着在第二种情况下,-5将其提升为相同的无符号类型,将其转换为4294967291.4亿多肯定比0-99更大!
让我们来看看你的两个例子中发生的事情.
从您的第一个示例开始,在此行中:
int rand = arc4random() % 100;
Run Code Online (Sandbox Code Playgroud)
arc4random()返回无符号值.那么它看起来像:
int rand = someUnsignedNumber % 100;
Run Code Online (Sandbox Code Playgroud)
这100是一个signed int,因此它被提升为与之相同的类型someUnsignedNumber,并应用了该%操作.之后你有:
int rand = someUnsignedNumberBetween0And99;
Run Code Online (Sandbox Code Playgroud)
分配该无符号数字int rand使其返回有符号数字.然后您的比较按预期进行.
在第二个示例中,您有以下这一行:
if (arc4random() % 100 <= chance)
Run Code Online (Sandbox Code Playgroud)
同样的事情发生了arc4random() % 100,产生了类似的东西:
if (someUnsignedNumberBetween0And99 <= chance)
Run Code Online (Sandbox Code Playgroud)
但在这里,chance是签名号码.它会得到提升,如上所述改变它的价值,你最终会看到你所看到的奇怪行为.
小智 5
傻,C傻类型系统......如果你读了man页面的arc4random(),你会发现,它的原型是
u_int32_t arc4random(void);
Run Code Online (Sandbox Code Playgroud)
所以它返回一个无符号整数.
当将其 - unsigned - 结果与另一个整数进行比较时,unsignedness"wins":另一个value(-5)被提升为无符号类型(u_int32_t在本例中),它会翻转(因为无符号整数"underflow"设计为像这样工作在C - 你会得到2 ^ 32 - 5)因此发生"错误"(即表现为意外)的比较.
当您将值显式分配给int(即已签名)变量时,由于比较是在两个签名类型之间,因此不会发生此促销,因此会按预期进行评估.
| 归档时间: |
|
| 查看次数: |
213 次 |
| 最近记录: |