3
    int chance = -5;
    int rand = arc4random() % 100;   // Number from 0 to 99
    if (rand <= chance) {            // This will never happen
        NSLog(@"This is... NOT POSSIBLE");
    }

事実上、これは決して起こりません。だが

    int chance = -5;
    if (arc4random() % 100 <= chance) {
        NSLog(@"This is... NOT POSSIBLE");
    }

ここでは、変数に格納する代わりに、乱数式を条件に直接配置しました。そして、条件が満たされます(時々)。

何故ですか?この動作をデバッグするにはどうすればよいですか?

4

2 に答える 2

6

プロモーション ルールを入力します。

arc4random符号なしの値を返します。つまり、2 番目のケースでは、-5が同じ unsigned 型に昇格され、 に変わり4294967291ます。40 億以上は、0 から 99 までのどの数字よりも確実に大きいです。

両方の例で何が起こるか見てみましょう。

  1. 最初の例から、次の行で:

    int rand = arc4random() % 100;
    

    arc4random()符号なしの値を返します。したがって、次のようになります。

    int rand = someUnsignedNumber % 100;
    

    100符号付き int であるため、 と同じ型に昇格されsomeUnsignedNumber%操作が適用されます。その後、次のようになります。

    int rand = someUnsignedNumberBetween0And99;
    

    その符号なしの番号を に割り当てると、符号付きの番号にint rand戻ります。その後、比較は期待どおりに進みます。

  2. 2 番目の例では、次の行があります。

    if (arc4random() % 100 <= chance)
    

    で同じことが起こりarc4random() % 100、次のような結果が得られます。

    if (someUnsignedNumberBetween0And99 <= chance)
    

    しかし、ここにchanceは署名された番号があります。上記のように昇格し、その値を変更すると、見ているような奇妙な動作が発生します。

于 2013-02-27T18:59:47.800 に答える
5

C のばかげた、ばかげた型システム... のman ページを読むarc4random()と、そのプロトタイプが

u_int32_t arc4random(void);

したがって、符号なし整数を返します。

その - 符号なし - 結果を別の整数と比較すると、符号なしが「勝つ」: 他の値 ( ) は符号なし型 (この場合) に-5昇格され、ロールオーバーします (符号なし整数の「アンダーフロー」はこのように動作するように設計されているため)。 u_int32_tC では ) が得られる2 ^ 32 - 5ため、「誤った」(つまり、予期しない動作) 比較が発生します。

int値を(つまりsigned ) 変数に明示的に代入すると、比較は 2 つの符号付き型の間で行われるため、この昇格は発生せず、期待どおりに評価されます。

于 2013-02-27T19:02:00.837 に答える