2009-06-26 15 views
7

(-1 >> 1)はなぜ-1になりますか?私はCで働いていますが、それは問題ではないと思います。(-1 >> 1)== -1なぜですか?

#include <stdio.h> 



int main() 
{ 
    int num1 = -1; 

    int num2 = (num1 >> 1); 

    printf("num1=%d", num1); 

    printf("\nnum2=%d", num2); 

    return 0; 
} 
+1

同じことがphp "echo -1 >> 1;"に当てはまります – merkuro

+0

もpythonで、答が言うように、負の数を1で埋めると意味があります。 –

答えて

23

符号付き整数はtwo's complementの表記で表されるためです。

-1は、11111111(8ビットの数字だった場合)です。

-1 >> 1は、明らかに符号が伸びて、11111111のままであることが明らかである。この動作はコンパイラによって異なりますが、Microsoftの場合、符号付き数値を右にシフトすると符号ビットがコピーされ、符号なし数値をシフトすると0が左端のビットに配置されます。

+4

これはCの未定義の動作です。 – bdonlan

+11

これは未定義の動作ではなく、符号ビットが符号付き右シフトで伝送されるかどうかは実装定義です。 – rlbond

+3

C99規格で6.5.7/5を探している人のために。 –

1

符号拡張:私は私が欠けているかを把握することはできません

...ここ

はカルクを行うCプログラムの例です。

5

負数をシフトするビットは、Cでの実装動作です。結果はプラットフォームによって異なり、理論的には完全に無意味である可能性があります。 C99規格(6.5.7.5)から:

E1 >> E2の結果は、E1 右シフトE2ビット位置です。 E1 に符号なしタイプがある場合、またはE1に 符号付きタイプおよび非負の値がある場合、結果の値は の商の整数部分E1/ 2^E2になります。 E1に符号付きの型があり、負の値が の場合、結果の値は となります。

この理由は、コンパイラがx86 SAR(Shift Arithmetic Right)命令を使用して>>を実装するためです。これは、符号拡張が行われることを意味します。一度値がシフトされると、最上位ビットは新しいMSBに複製されます。シフト演算右(SAR)と シフト論理右(SHR)

命令は、(以下 上位ビット位置に向かって)右に先 オペランドのビットをシフト :intel manualsから。各 シフト・カウントのために、デスティネーション・オペランドの最下位ビット はCFフラグに シフトされ、最も 上位ビットがセットされるか、または は、命令タイプに応じてクリア。 SHR命令は、 の最上位ビットをクリアします(インテル®64およびIA-32 アーキテクチャー・ソフトウェア開発者の マニュアル、第1巻の図7-8 を参照)。 SAR命令 は、デスティネーション・オペランドの元の値 の符号(大部分は 有意ビット)に対応する最上位の ビットを設定またはクリアします。 は実際に、 SAR命令がシフトされていない値の 符号(インテル64に 図7-9を参照し、IA-32 アーキテクチャー・ソフトウェア・デベロッパーズ・ マニュアル、第1巻で空 ビット位置のシフトされた値を満たします)。

+1

引用符で囲まれた文章では、(10 >> -1)のような操作は定義されていません。右のオペランドは-1です。 – rlbond

+0

ああ、私の間違い。修正されます。 – bdonlan

+0

6.5.7/5ではなく6.5.7/3です。 –

3

右シフトして左端のビットが1の場合、一部のプラットフォーム/コンパイラは0を持ち、あるものは1を保持し、新しい左端のビットを1にします。これにより、 numberは負のままで、符号拡張と呼ばれます。

((unsigned) -1) >> 1を試してみると、符号なしの右シフトが行われるため、常に0ビットシフトします。

11

Arithmetic right shiftsigned numberに移行する際の符号を保存する:

11111111 (-1) will stay 11111111 (-1) 

対照的に、Logical right shiftは符号を保存しないであろう。

11111111 (-1) will become 01111111 (127) 

コードが明確算術シフトを行い、そう符号ビット(MSB)が繰り返されます。演算子(>>)は、使用しているプラ​​ットフォームの実装の詳細によって異なります。ほとんどの場合、それは算術シフトです。

また、11111111は、表現によって2つの異なる意味を持つことができます。これは彼らがシフトされる方法にも影響します。

  • 11111111は255を表します。右にシフトすると、MSBが符号ビットではないため、符号が保持されません。
  • 署名した場合、11111111は-1を表します。これを右に算術的にシフトすると、符号が保持されます。
関連する問題