2

誰かが私に理由を説明できますか:

x = x << 1;
x = x >> 1;

と:

x = (x << 1) >> 1;

Cで異なる答えを生成しますか? x*uint8_t* 型 (符号なし 1 バイト長整数) です。たとえば128 (10000000)、最初のケースで渡すと返されますが0(最上位ビットが脱落すると予想されます)、2番目のケースでは元の が返されます128。何故ですか?これらの式は同等であると思いますか?

4

2 に答える 2

13

これは整数の昇格によるもので、どちらの場合もビット単位のシフトの両方のオペランドがintに昇格されます。2 番目のケースでは:

x = (x << 1) >> 1;

の結果はintx << 1になるため、シフトされたビットは保持され、次のステップで再びシフトバックされるintとして使用できます。最初のケースでは:

x = x << 1;
x = x >> 1;

割り当て直すとx、余分なビットが失われます。ドラフトC99標準セクションから、次の6.5.7 Bit-wise shift operatorsように書かれています:

整数昇格は各オペランドで実行されます。

整数の昇格については、6.3.1.1 ブール値、文字、および整数の段落2のセクションで説明されています。

int が元の型のすべての値を表すことができる場合、値は int に変換されます。それ以外の場合は、unsigned int に変換されます。これらは整数プロモーションと呼ばれます。48)

この最後の部分は、なぜint256からuint8_tへの変換が私たちに与えるの0ですか? 変換は、 Conversionsセクションの下にあるセクション6.3.1.3 Signed and unsigned integersでカバーされており、次のように述べています。

それ以外の場合、新しい型が符号なしの場合、値が新しい型の範囲内になるまで、新しい型で表現できる最大値よりも 1 多い値を繰り返し加算または減算することによって、値が変換されます。49)

したがって、256 - (255+1)どちらが です0

于 2014-03-28T00:42:22.693 に答える
6

ビットシフトすると、結果は に昇格しintます。最初の例では、毎回 int を uint8_t に変換し直し、中間データを失います。しかし、2 番目の例では、シフトバック時に int の結果を保持します。

于 2014-03-28T00:42:30.467 に答える