我在使用随机数做一些iOS内容时偶然发现了一个非常令人惊讶的问题。
比较这些:
A)
int xOffsetSign = randomIntWithUpperLimit(2) ? 1:-1;
int yOffsetSign = randomIntWithUpperLimit(2) ? 1:-1;
int xOffset = randomIntWithUpperLimit(50) * xOffsetSign;
int yOffset = randomIntWithUpperLimit(50) * yOffsetSign;
b)中
int xOffset = randomIntWithUpperLimit(50) * randomIntWithUpperLimit(2) ? 1:-1;
int yOffset = randomIntWithUpperLimit(50) * randomIntWithUpperLimit(2) ? 1:-1;
这是随机函数:
static inline int randomIntWithUpperLimit(unsigned int upperLimit) {
return arc4random_uniform(upperLimit);
}
在我看来,a)和b)都应该产生[-49,49]范围内的随机数。但是,只有a)有效。 b)仅产生[-1,1]范围内的数字。
似乎每个调用的第二个随机部分首先得到解析,缓存,然后重新用于行的第一部分,而不管上限。
有人可以解释并澄清为什么b)不会工作吗?
答案 0 :(得分:1)
这是一个优先问题。
int yOffset = randomIntWithUpperLimit(50) * randomIntWithUpperLimit(2) ? 1 : -1;
与
相同int yOffset = (randomIntWithUpperLimit(50) * randomIntWithUpperLimit(2)) ? 1 : -1;
这是一个常见的问题,许多编码标准都需要围绕?:
构造的括号。使用此:
int yOffset = randomIntWithUpperLimit(50) * (randomIntWithUpperLimit(2) ? 1 : -1);
答案 1 :(得分:0)
这与运营商关联性和优先级有关。发生的事情是你正在评估你的两个随机数,然后在-1和1之间选择。
你可能想要B这样的东西:
int xOffset = randomIntWithUpperLimit(50) * (randomIntWithUpperLimit(2) ? 1:-1);
int yOffset = randomIntWithUpperLimit(50) * (randomIntWithUpperLimit(2) ? 1:-1);
这将确保您在1到-1之间进行选择,然后按0到49范围内的随机数进行选择。
答案 2 :(得分:-1)
?:
运算符的优先级低于*
运算符
使用括号
randomIntWithUpperLimit(50) * (randomIntWithUpperLimit(2) ? 1:-1);