5

私はビット シフト演算子を使用していました (私の質問Bit Array Equalityを参照してください)。SO ユーザーが私のシフト オペランドの計算のバグを指摘しました。[0,31] ではなく [1,32] の範囲を計算していました。 int の場合。(SO コミュニティに万歳!)

問題を修正する際に、次の動作を見つけて驚きました。

-1 << 32 == -1

実際、それはbs(n) = n のサイズ (ビット単位n << s) としてコンパイルされている (または CLR によって解釈されている - 私は IL をチェックしていませんでした)ように見えます。n << s % bs(n)

私は期待していたでしょう:

-1 << 32 == 0

コンパイラは、ターゲットのサイズを超えてシフトしていることに気づき、間違いを修正しているようです。

これは純粋に学術的な質問ですが、これが仕様で定義されているかどうか (私は7.8 Shift operatorで何も見つかりませんでした)、未定義の動作の偶然の事実であるかどうか、またはこれがバグを生成する可能性がある場合があるかどうかは誰にもわかりませんか?

4

1 に答える 1

9

仕様の関連部分は次のとおりだと思います。

事前定義された演算子の場合、シフトするビット数は次のように計算されます。

  • x の型が int または uint の場合、シフト カウントは count の下位 5 ビットで指定されます。つまり、カウントと 0x1F からシフト カウントが計算されます。

  • x の型が long または ulong の場合、シフト カウントは count の下位 6 ビットで与えられます。つまり、カウントと 0x3F からシフト カウントが計算されます。

結果のシフト カウントがゼロの場合、シフト演算子は単純に x の値を返します。

320x20です。式0x20 & 0x1Fは に評価され0ます。したがって、シフト カウントはゼロであり、シフトは行われません。式-1 << 32(または any x << 32) は元の値を返すだけです。

于 2010-02-24T14:40:36.890 に答える