2

例えば:

unsigned int i = ~0;

結果:割り当て可能な最大数i

signed int y = ~0;

結果:-1

なぜ私は得るの-1ですか?に割り当てることができる最大数を取得するべきではありませんyか?

4

7 に答える 7

7

両方4294967295(aka UINT_MAX) と-1の同じバイナリ表現0xFFFFFFFFまたは 32 ビットがすべて に設定されてい1ます。これは、符号付き数値が2 の補数を使用して表されるためです。負の数の MSB (最上位ビット) は に設定され1、その値は残りのビットを反転し、 を加算1して乗算することによって決定され-1ます。したがって、MSB が に設定され1、残りのビットも に設定されている1場合、それらを反転し (32 個のゼロを取得)、加算1( を取得1) し、 を乗算し-1て最終的に を取得し-1ます。

これにより、CPU は負の数に対して特別な例外を必要としないため、計算が容易になります。たとえば、0xFFFFFFFF(-1) とを足してみてください1。32 ビットの余地しかないため、これはオーバーフローし、結果は0期待どおりになります。

詳細については、次を参照してください。

http://en.wikipedia.org/wiki/Two%27s_complement

于 2012-10-30T21:34:14.157 に答える
5
unsigned int i  = ~0;

結果: i に割り当てることができる最大数

通常、必ずしもそうではありません。式は、すべての (非パディング) ビットが設定~0された として評価されます。intC 標準では、符号付き整数の 3 つの表現が許可されています。

  • この場合、それ~0 = -1を に代入すると、 がunsigned int得られ(-1) + (UINT_MAX + 1) = UINT_MAXます。
  • 1 の補数。この場合~0、負のゼロまたはトラップ表現のいずれかです。負のゼロの場合、への代入unsigned intは 0 になります。
  • 符号と大きさ、この場合~0INT_MIN == -INT_MAXであり、それを に代入すると、幅 (符号なし整数型のunsigned int値ビット数 + 1 [符号ビットの場合は値ビット数 + 1]) を持つ可能性(UINT_MAX + 1) - INT_MAX1ほとんどありません。 ] の幅が の幅と同じである一般的なケースでは、のunsigned intそれよりも小さい (符号付き整数型の場合) 。int2^(WIDTH - 1) + 1unsigned intint

初期化

unsigned int i = ~0u;

常にi値を保持しますUINT_MAX

signed int y = ~0;

結果: -1

上で述べたように、符号付き整数の表現が 2 の補数を使用している場合のみです (現在では、これが最も一般的な表現です)。

于 2012-10-30T22:00:31.137 に答える
4

~0は、すべてのビットが 1 に設定された単なるです。これをint解釈するunsignedと、 と同等になりUINT_MAXます。と解釈するsignedと となります-1

32 ビット整数を想定すると、次のようになります。

 0 = 0x00000000 =  0 (signed) = 0 (unsigned)
~0 = 0xffffffff = -1 (signed) = UINT_MAX (unsigned)
于 2012-10-30T21:26:57.417 に答える
2

パウロの答えは絶対に正しいです。〜0を使用する代わりに、次を使用できます。

#include <limits.h>

signed int y = INT_MAX;
unsigned int x = UINT_MAX;

そして今、あなたが値をチェックするならば:

printf("x = %u\ny = %d\n", UINT_MAX, INT_MAX);

システムの最大値を確認できます。

于 2012-10-30T21:40:04.977 に答える
1

いいえ、~ビット単位の NOT演算子であり、型演算子の最大値ではないためです。unsigned として解釈されると unsigned で表現可能な最大数が得られ、signed int として解釈されると -1 が得られ~0ますint1

于 2012-10-30T21:29:06.633 に答える
0

http://en.wikipedia.org/wiki/Two%27s_complementを調べて、ブール代数と論理設計について少し学んでください。また、バイナリでカウントする方法と、バイナリでの足し算と引き算の方法を学習すると、これがさらに説明されます。

C 言語はこの形式の数値を使用したため、最大の数値を見つけるには 0x7FFFFFFF を使用する必要があります。(使用する各バイトに 2 つの FF を使用し、左端のバイトは 7 です。) これを理解するには、16 進数とその動作を調べる必要があります。

次に、符号なしの同等物について説明します。符号付きの数値では、数値の下半分が負になります (0 は正の数値と見なされるため、実際には負の数値は正の数値よりも 1 大きくカウントされます)。符号なしの数値はすべて正です。したがって、理論的には、32ビットintの最大数は2 ^ 32ですが、0はまだ正としてカウントされるため、実際には2 ^ 32-1であり、符号付き数値の半分は負です。これは、前の数値 2^32 を 2 で割ることを意味します。32 は指数であるため、両側に 2^31 の数値が得られます。0 が正であることは、符号付き 32 ビット int の範囲が (-2^31, 2^31- 1)。

範囲を比較するだけです: unsigned 32 bit int: (0, 2^32-1) signed 32 bit int: (-2^31, 2^32-1) unsigned 16 bit int: (0, 2^16-1)符号付き 16 ビット整数: (-2^15, 2^15-1)

ここでパターンを見ることができるはずです。~0 のことを説明するには、もう少し時間がかかります。これは、2 進数での減算に関係しています。1 を足してすべてのビットを反転させてから、2 つの数値を足し合わせるだけです。C は舞台裏でこれを行い、多くのプロセッサ (x86 および x64 のプロセッサ ラインを含む) も同様です。このため、負の数をカウント ダウンのように格納するのが最善であり、2 の補数では加算された 1 も隠されます。 . 0 は正と見なされるため、負の数は 0 の値を持つことができないため、自動的に -1 (ビット反転後の正の 1) が追加されます。負の数をデコードするときは、これを考慮する必要があります。

于 2013-04-28T23:59:29.273 に答える
0

2 の補数のマシンを使用している必要があります。

于 2012-10-30T21:29:49.740 に答える