0

在用随机数做一些 iOS 东西时,我偶然发现了一个非常令人惊讶的问题。

比较这些:

一个)

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) 不起作用吗?

4

3 回答 3

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);
于 2012-10-12T11:30:26.043 回答
0

这与运算符关联性和优先级有关。发生的事情是您正在评估两个随机数,然后在 -1 和 1 之间进行选择。

你可能想要这样的 B:

int xOffset = randomIntWithUpperLimit(50) * (randomIntWithUpperLimit(2) ? 1:-1);
int yOffset = randomIntWithUpperLimit(50) * (randomIntWithUpperLimit(2) ? 1:-1);

这将确保您在 1 和 -1 之间进行选择,然后将其乘以 0 到 49 范围内的随机数。

于 2012-10-12T11:31:40.190 回答
-1

运算符的优先级?:低于*运算符

像这样使用括号

randomIntWithUpperLimit(50) * (randomIntWithUpperLimit(2) ? 1:-1);
于 2012-10-12T11:31:56.807 回答