これは、符号付き整数のビット表現に関する疑問です。たとえば、-1を表す場合は、(+1)の2の補数に相当します。したがって、-1は0xFFFFFFFとして表されます。今では31をシフトして結果を印刷すると-1に戻ります。負の数のビット表現
signed int a = -1;
printf(("The number is %d ",(a>>31));//this prints as -1
どのようにビットが負の数で表されているか説明してください。
ありがとうございました。
これは、符号付き整数のビット表現に関する疑問です。たとえば、-1を表す場合は、(+1)の2の補数に相当します。したがって、-1は0xFFFFFFFとして表されます。今では31をシフトして結果を印刷すると-1に戻ります。負の数のビット表現
signed int a = -1;
printf(("The number is %d ",(a>>31));//this prints as -1
どのようにビットが負の数で表されているか説明してください。
ありがとうございました。
トップビットがゼロの場合、数値は正です。 1のとき、数値は負です。
負の数は右の負の数を維持するために最上位ビットとして「1」にシフト保つシフト。だからあなたはその答えを得ているのです。
より約2の補数の場合は、this Stackoverflow questionを参照してください。
@StoborいくつかのCの実装ではなく1の上位ビットに0をシフトすることができることを指摘[ウィキペディアで確認。] Javaでは、それはdependably算術シフトです。
しかし、質問者によって与えられた出力は、彼のコンパイラが算術シフトを行っていることを示しています。
two's complementの説明をご覧ください。それは助けになるはずです。
これは符号ビットを保持し、署名された数の仮数部をシフト算術シフト演算です。最上位ビットに
歓声
C標準は、それが負の右シフトは、(必ずしも符号付き)か否かを未定義のまま整数(右論理シフト)ゼロをシフトまたはサインビット(算術右シフト)。選択するのは実装次第です。
その結果、移植可能なコードは、それが負の数の上で右シフトを実行しないことを保証します。シフトする前に値を対応する符号なしの値に変換するか(論理シフト右を使用すること、保証されていないビットにゼロを入れることが保証されているか)、値が正であることを保証するか、出力の変化を許容します。
シフト後に最上位ビット(またはビット)に "または"が入る可能性があります。 – Nosredna
ありがとう、私はまだ私のdoyubt yet.Soをクリアしていないすべてのanswers.Guessのために多くのコンパイラやハードウェアですか? –
@Maddy:ハードウェアとコンパイラによって異なります。たとえば、特定のCPUに論理シフト権(LSR)のみがあり、算術シフト権(ASR)がない場合、そのマシンのコンパイラはLSRを使用し、存在しないASRは使用しません。コンパイラにも依存します。マシンにASRとLSRの両方がある場合でも、コンパイラライターは、いくつかの理由のいずれかによって、符号付きおよび符号なしの両方の量に対してLSRを使用することを決定する可能性があります。より速いかもしれません。同じコンパイラも実行される他のプラットフォームと一貫しているかもしれません。コンパイラを書く人がASRを好きではないかもしれません。 –
基本的に右シフトには2つのタイプがあります。符号なし右シフトと符号付き右シフト。符号なし右シフトはビットを右にシフトし、最下位ビットを失わせ、最上位ビットを0に置き換えます。符号付き右シフトでは、ビットが右にシフトされ、重要なビットが失われ、最上位のビットが保存される。符号付き右シフトは、2のべき乗(シフトされた場所の数に対応する)で数を除算しますが、符号なしシフトは論理シフト演算です。それが動作するデータ・タイプが符号なしの場合
「>>」演算子は、符号なし右シフトを行い、それが動作しているデータ・タイプが署名されている場合には、符号付き右シフトを行います。だから、あなたがしなければならないことは、目的の結果を得るためにビット操作を実行する前に、オブジェクトを符号なし整数型にキャストすることです。
符号付き整数の場合は必ずしも '符号付きシフト'である必要はありませんが(非常に一般的ですが)、コンパイラやハードウェアによって異なります。 –
うん。そのとおり。私は、x86のいくつかの亜種を実行し、GCCでコンパイルしている、うまく動作するラップトップ/デスクトップ/サーバマシンで長い間プログラミングを行ってきましたが、現在のアプリケーションで想定していることと、保証。 –
EDIT:unsigned int型は、少なくとも32ビット幅である
unsigned int a = -1;
printf(("The number is %d ",(a>>31));//this prints as -1
場合は、お使いのコンパイラは本当に生産するために許可されていません。以下が書かれたとき、問題のコードは次のように書かれていました-1を出力します(小さな値は、unsigned値をintにキャストしてからprintfに渡す必要があります)。
aは符号なし整数であるため、-1を代入するとUINT_MAX(-1を法とするUINT_MAX + 1に一致する最小の非負の値)を与える必要があります。 unsigned intがプラットフォーム上で少なくとも32ビットを持つ限り、その符号なし量を31右にシフトした結果は、UINT_MAXを2^31で割ったものになります。これはint内に収まる必要があります。 (unsigned intが31ビット以下であれば、シフトの結果が指定されていないため、好きなものを生成することができます)。
別の角度から見ると:2^Nで割り切れるようにNビット(符号拡張)の右シフトを考えると、DOWN(マイナスの無限大に向かって、0に向かって)に丸めます。拡張)は何回でも-1を生成し続けます。 – vladr