web-dev-qa-db-ja.com

Cでの負の数の表現?

Cはどのように負の整数を表しますか?

2の補数表現によるものですか、それともMSB(最上位ビット)の使用によるものですか?

-116進数はffffffffです。

だから私のためにこれを明確にしてください。

22
1s2a3n4j5e6e7v

ISO C(C99 section 6.2.6.2/2この場合、標準のその後の反復に引き継がれます(a))は、実装が整数データタイプ、2の補数、1の補数、または符号/大きさの3つの異なる表現のいずれかを選択する必要があると述べています(ただし、2の補数の実装が他の実装をはるかに上回っている可能性が非常に高いです)。

これらすべての表現において、正の数は同一であり、唯一の違いは負の数です。

正の数の負の表現を取得するには、次のようにします。

  • すべてのビットを反転してから、2の補数に対して1を追加します。
  • 1の補数のすべてのビットを反転します。
  • 符号/大きさの符号ビットだけを反転します。

これは、以下の表で確認できます。

番号| 2の補数| 1の補数|符号/大きさ
 ======= | ===================== | ============ ========= | ==================== 
 5 | 0000 0000 0000 0101 | 0000 0000 0000 0101 | 0000 0000 0000 0101 
-5 | 1111 1111 1111 1011 | 1111 1111 1111 1010 | 1000 0000 0000 0101 

ISOは、表現ですべてのビットが使用されることを義務付けていないことに注意してください。符号ビット、値ビット、パディングビットの概念を紹介しています。今まで実際に見たことがありませんパディングビットを使用した実装ですが、C99の理論的根拠のドキュメントから、次の説明があります。

マシンが16ビットショートのペア(それぞれに独自の符号ビットを持つ)を使用して32ビット整数を構成し、この32ビット整数で使用される場合、下位ショートの符号ビットが無視されるとします。次に、32ビットのsigned intとして、32ビットのsigned intの値を決定する際に無視されるパディングビット(32ビットの中央)があります。ただし、この32ビットアイテムが32ビットのunsigned intとして扱われる場合、そのパディングビットはユーザーのプログラムに表示されます。 C委員会は、このように動作するマシンがあると言われました。これが、C99にパディングビットが追加された理由の1つです。

彼らが参照していた可能性のあるマシンは、Datacraft 6024(およびHarris Corpの後継機)だったと思います。これらのマシンでは、符号付き整数に24ビットのワードが使用されていましたが、より広いタイプが必要な場合は、ワードの1つの符号ビットを無視して2つを47ビット値としてつなぎ合わせました。

+---------+-----------+--------+-----------+
| sign(1) | value(23) | pad(1) | value(23) |
+---------+-----------+--------+-----------+
\____________________/ \___________________/
      upper Word            lower Word

(a) 興味深いことに、他の2つのメソッドを実際に使用する最新の実装が不足していることを考えると、2の補数を1つの真のメソッドとして受け入れるようにというプッシュがありました。これは、C++標準では かなり長い道のり (WG21はこれを担当するワークグループです)、現在はCでも検討されているようです(WG14によって)。

42
paxdiablo

Cは、符号付き整数の符号/大きさ、1の補数、および2の補数表現を許可します。最も一般的なハードウェアは、整数に2の補数を使用し、浮動小数点に符号/大きさを使用します(さらに別の可能性として、浮動小数点指数の「バイアス」表現)。

12
Jerry Coffin

-16進数の-1はffffffffです。それで、この点に関して私を明確にしてください。

2の補数(最も一般的に使用される表現)では、最上位ビット(MSB)を除く各ビットは、右から左(桁違いに増加)の値が2になります。n ここで、nはゼロから1ずつ増加します。 MSBの値は-2です。n

したがって、たとえば8ビットの2の補数整数では、MSBの場所の値は-2になります。7 (-128)なので、2進数:1111 11112 -128 + 01111111に等しい2 = -128 + 127 = -1

2の補数の便利な機能の1つは、プロセッサのALUが、右側のオペランドの2の補数を形成することにより、減算を実行するために加算器ブロックのみを必要とすることです。たとえば、10-6は10 +(-6)と同等です。 8ビットバイナリ(説明を簡単にするため)では、これは次のようになります。

   0000 1010
  +1111 1010
   ---------
[1]0000 0100  = 4 (decimal)

ここで、[1]は破棄されたキャリービットです。もう一つの例; 10-11 == 10 +(-11):

   0000 1010
  +1111 0101
   ---------
   1111 1111  = -1 (decimal)

2の補数のもう1つの特徴は、ゼロを表す単一の値があるのに対し、符号の大きさと1の補数にはそれぞれ2つの値があることです。 +0および-0。

7
Clifford

整数型の場合、通常は2の補数です(実装固有)。浮動小数点には、符号ビットがあります。

1
JoshD