0

乱数を使って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]の範囲の数値のみを生成します。

各呼び出しの2番目のランダムな部分が最初に解決され、キャッシュされてから、上限に関係なく、行の最初の部分で再利用されるようです。

誰かが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 に答える