誰かが私に理由を説明できますか:
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 の結果を保持します。