誰かが私に理由を説明できますか:
x = x << 1;
x = x >> 1;
と:
x = (x << 1) >> 1;
Cで異なる答えを生成しますか? x*uint8_t* 型 (符号なし 1 バイト長整数) です。たとえば128 (10000000)、最初のケースで渡すと返されますが0(最上位ビットが脱落すると予想されます)、2番目のケースでは元の が返されます128。何故ですか?これらの式は同等であると思いますか?
誰かが私に理由を説明できますか:
x = x << 1;
x = x >> 1;
と:
x = (x << 1) >> 1;
Cで異なる答えを生成しますか? x*uint8_t* 型 (符号なし 1 バイト長整数) です。たとえば128 (10000000)、最初のケースで渡すと返されますが0(最上位ビットが脱落すると予想されます)、2番目のケースでは元の が返されます128。何故ですか?これらの式は同等であると思いますか?
これは整数の昇格によるもので、どちらの場合もビット単位のシフトの両方のオペランドが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)
この最後の部分は、なぜint値256からuint8_tへの変換が私たちに与えるの0ですか? 変換は、 Conversionsセクションの下にあるセクション6.3.1.3 Signed and unsigned integersでカバーされており、次のように述べています。
それ以外の場合、新しい型が符号なしの場合、値が新しい型の範囲内になるまで、新しい型で表現できる最大値よりも 1 多い値を繰り返し加算または減算することによって、値が変換されます。49)
したがって、256 - (255+1)どちらが です0。
ビットシフトすると、結果は に昇格しintます。最初の例では、毎回 int を uint8_t に変換し直し、中間データを失います。しかし、2 番目の例では、シフトバック時に int の結果を保持します。