符号付き整数と符号なし整数の違いは何ですか


91

符号付き整数と符号なし整数の違いは何ですか?


5
これは本当の質問であり、答えはそれほど単純ではなく、微妙です。
R .. GitHub STOP HELPING ICE

再開するための投票。重複しているかもしれませんが、それは間違いなく本当の問題です。
ブライアン

4
Re:「重複している可能性があります」-Cのunsignedintとsignedintの違いは何ですか?
eldarerathis 2011

多くの言語でタグが使用されているため、タグを追加する必要があります。
Juan Boero 2015年

この質問には、詳しく説明する章が必要な場合があります。インとアウトを知りたい場合は、詳細について符号なし整数と符号付き整数を確認してください。
匿名

回答:


113

ご存知かもしれませんが、intsは内部的にバイナリで格納されます。通常、にintは32ビットが含まれますが、環境によっては16ビットまたは64ビット(または異なる数、通常は2の累乗である必要はありません)が含まれる場合があります。

しかし、この例では、4ビット整数を見てみましょう。小さいですが、説明の目的で役立ちます。

このような整数には4ビットがあるため、16個の値のいずれかをとることができます。16は2の4乗、つまり2 x 2 x 2 x 2です。これらの値は何ですか?答えは、この整数がaであるsigned intunsigned int。であるかによって異なります。を使用するunsigned intと、値が負になることはありません。値に関連付けられた符号はありません。4ビットの16の可能な値はunsigned int次のとおりです。

bits  value
0000    0
0001    1
0010    2
0011    3
0100    4
0101    5
0110    6
0111    7
1000    8
1001    9
1010   10
1011   11
1100   12
1101   13
1110   14
1111   15

...そしてこれが4ビットの16の可能な値ですsigned int

bits  value
0000    0
0001    1
0010    2
0011    3
0100    4
0101    5
0110    6
0111    7
1000   -8
1001   -7
1010   -6
1011   -5
1100   -4
1101   -3
1110   -2
1111   -1

ご覧のとおり、signed intsの最上位ビットは1、数値が負の場合に限ります。そのため、signed intsの場合、このビットは「符号ビット」と呼ばれます。


11
おそらく指摘する価値があるのは、これが2の補数形式であり、今日広く使用されていることは確かです。符号付き整数、特に1の補数を表す他の方法もあります。
Schedler 2011

正しい。また、ISO9899 C標準では、1の補数または2の補数のいずれかを使用する必要はありません。実際に機能するその他の規則は許容されます。
マリポサでのビルエヴァンス2011

1
2の補数は必須で(unsigned)(-1)はありませんが、unsigned(バイナリ表現とは関係なく)の表現可能な最大値である必要があります。これは、2の補数には自明に当てはまりますが、他の表現には当てはまりません。
rubenvb 2011年

3
@BillEvansatMariposa:標準では、符号付き整数には、符号+大きさ、2の補数、1の補数の3つの表現が許可されているとされています。その他のプログラムには見えなければならないであろうし、これらの3の一つとして認識される
アレクセイフルンゼ

わかりました、しかしボンネットの下で!本当に何が起こっているのですか!SIGNED番号とUNSIGNED番号の違いは何ですか?マシンはどのように計算を管理しますか?値を別の値から差し引くだけですか?1111 = 15と1111 = -1の違いは何ですか?
ミハイルジョルジュスク2016年

19

intunsigned intは2つの異なる整数型です。(intも呼ぶことができるsigned int、または単にsigned;unsigned intとも呼ばれることができますunsigned。)

名前が暗示するように、intある符号付き整数型、及びunsigned intある符号なし整数型。つまり、intは負の値を表すことができ、非負の値unsigned intのみを表すことができます。

C言語は、これらのタイプの範囲にいくつかの要件を課します。の範囲はint少なくとも-32767...+32767unsigned intなければならず、の範囲は少なくとも0...でなければなりません65535。これは、両方のタイプが少なくとも16ビットでなければならないことを意味します。多くのシステムでは32ビット、一部のシステムでは64ビットです。int最近のほとんどのシステムで使用されている2の補数表現のため、通常は余分な負の値があります。

おそらく最も重要な違いは、符号付き演算と符号なし演算の動作です。署名付きのint場合、オーバーフローの動作は未定義です。の場合unsigned int、オーバーフローはありません。タイプの範囲外の値を生成する操作はすべてラップアラウンドしますUINT_MAX + 1U == 0U。たとえば、。

符号付きまたは符号なしの整数型は、数学整数の無限セットのサブ範囲をモデル化します。タイプの範囲内の値を操作している限り、すべてが機能します。型の下限または上限に近づくと、不連続性が発生し、予期しない結果が生じる可能性があります。符号付き整数型のため、問題が超える、非常に大きな負と正の値の発生INT_MININT_MAX。符号なし整数型の場合、非常に大きな正の値とゼロで問題が発生します。これはバグの原因となる可能性があります。たとえば、これは無限ループです。

for (unsigned int i = 10; i >= 0; i --) [
    printf("%u\n", i);
}

i常にゼロ以上であるため。これが符号なし型の性質です。(ループ内で、iがゼロの場合、i--その値はに設定されUINT_MAXます。)


12

たとえば、物事を数えるためだけに使用されている場合、特定の整数変数に格納されている値が常に正であることが事前にわかっている場合があります。このような場合、のように、変数を符号なしとして宣言できますunsigned int num student;。このような宣言を使用すると、許容される整数値の範囲(32ビットコンパイラの場合)は、-2147483648から+2147483647の範囲から0から4294967295の範囲にシフトします。したがって、整数を符号なしとして宣言すると、可能な最大のサイズのほぼ2倍になります。それ以外の場合に保持できる値。


@Alex私は10分前にその答えを編集している最中でしたが、それは同じです。笑
スカルド2011年

12

素人の用語では、unsigned intは負にできない整数であるため、想定できる正の値の範囲が広くなります。符号付き整数は、負の値になる可能性がある整数ですが、想定できる負の値が増える代わりに、正の範囲が狭くなります。


0

実際には、2つの違いがあります。

  1. 印刷coutC ++またはprintfCなど):符号なし整数ビット表現は、印刷関数によって非負の整数として解釈されます。
  2. 順序付け:順序付けは、符号付きまたは符号なしの仕様によって異なります。

このコードは、順序付け基準を使用して整数を識別できます。

char a = 0;
a--;
if (0 < a)
    printf("unsigned");
else
    printf("signed");

これが負の数を扱うものとそうでないものの違いを説明している場合はそうではありません。それはこの投稿に大いに役立つでしょう。
ダニエルジャクソン

@DanielJacksonあなたの言うことがはっきりしない。charは、コンパイラーに応じて負または正と見なすことができます。コードの出力は、コンパイラが選択するものによって異なり、これは符号付きと符号なしの違いを示しています。
MinimusHeximus19年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.