符号付き整数と符号なし整数の違いは何ですか?
符号付き整数と符号なし整数の違いは何ですか?
回答:
ご存知かもしれませんが、int
sは内部的にバイナリで格納されます。通常、にint
は32ビットが含まれますが、環境によっては16ビットまたは64ビット(または異なる数、通常は2の累乗である必要はありません)が含まれる場合があります。
しかし、この例では、4ビット整数を見てみましょう。小さいですが、説明の目的で役立ちます。
このような整数には4ビットがあるため、16個の値のいずれかをとることができます。16は2の4乗、つまり2 x 2 x 2 x 2です。これらの値は何ですか?答えは、この整数がaであるsigned int
かunsigned 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 int
sの最上位ビットは1
、数値が負の場合に限ります。そのため、signed int
sの場合、このビットは「符号ビット」と呼ばれます。
(unsigned)(-1)
はありませんが、unsigned
(バイナリ表現とは関係なく)の表現可能な最大値である必要があります。これは、2の補数には自明に当てはまりますが、他の表現には当てはまりません。
int
とunsigned int
は2つの異なる整数型です。(int
も呼ぶことができるsigned int
、または単にsigned
;unsigned int
とも呼ばれることができますunsigned
。)
名前が暗示するように、int
ある符号付き整数型、及びunsigned int
ある符号なし整数型。つまり、int
は負の値を表すことができ、非負の値unsigned int
のみを表すことができます。
C言語は、これらのタイプの範囲にいくつかの要件を課します。の範囲はint
少なくとも-32767
...+32767
でunsigned int
なければならず、の範囲は少なくとも0
...でなければなりません65535
。これは、両方のタイプが少なくとも16ビットでなければならないことを意味します。多くのシステムでは32ビット、一部のシステムでは64ビットです。int
最近のほとんどのシステムで使用されている2の補数表現のため、通常は余分な負の値があります。
おそらく最も重要な違いは、符号付き演算と符号なし演算の動作です。署名付きのint
場合、オーバーフローの動作は未定義です。の場合unsigned int
、オーバーフローはありません。タイプの範囲外の値を生成する操作はすべてラップアラウンドしますUINT_MAX + 1U == 0U
。たとえば、。
符号付きまたは符号なしの整数型は、数学整数の無限セットのサブ範囲をモデル化します。タイプの範囲内の値を操作している限り、すべてが機能します。型の下限または上限に近づくと、不連続性が発生し、予期しない結果が生じる可能性があります。符号付き整数型のため、問題が超える、非常に大きな負と正の値の発生INT_MIN
とINT_MAX
。符号なし整数型の場合、非常に大きな正の値とゼロで問題が発生します。これはバグの原因となる可能性があります。たとえば、これは無限ループです。
for (unsigned int i = 10; i >= 0; i --) [
printf("%u\n", i);
}
i
は常にゼロ以上であるため。これが符号なし型の性質です。(ループ内で、i
がゼロの場合、i--
その値はに設定されUINT_MAX
ます。)
たとえば、物事を数えるためだけに使用されている場合、特定の整数変数に格納されている値が常に正であることが事前にわかっている場合があります。このような場合、のように、変数を符号なしとして宣言できますunsigned int num student;
。このような宣言を使用すると、許容される整数値の範囲(32ビットコンパイラの場合)は、-2147483648から+2147483647の範囲から0から4294967295の範囲にシフトします。したがって、整数を符号なしとして宣言すると、可能な最大のサイズのほぼ2倍になります。それ以外の場合に保持できる値。
素人の用語では、unsigned intは負にできない整数であるため、想定できる正の値の範囲が広くなります。符号付き整数は、負の値になる可能性がある整数ですが、想定できる負の値が増える代わりに、正の範囲が狭くなります。
実際には、2つの違いがあります。
cout
C ++またはprintf
Cなど):符号なし整数ビット表現は、印刷関数によって非負の整数として解釈されます。このコードは、順序付け基準を使用して整数を識別できます。
char a = 0;
a--;
if (0 < a)
printf("unsigned");
else
printf("signed");