在同一行代码上生成两个随机数?

时间:2012-10-12 11:28:17

标签: objective-c random inline arc4random

我在使用随机数做一些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)不会工作吗?

3 个答案:

答案 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);