web-dev-qa-db-ja.com

Cで符号なしintをintにキャストまたは変換するにはどうすればよいですか?

質問が奇妙に思われる場合、私の謝罪。私は自分のコードをデバッグしていますが、これが問題のようですが、よくわかりません。

ありがとう!

16
Eric Brotto

動作をどのようにするかによって異なります。 intは、unsigned intが保持できる値の多くを保持できません。

通常通りキャストできます:

int signedInt = (int) myUnsigned;

ただし、unsignedの値がintが保持できる最大値を超えている場合、これにより問題が発生します。これは、特に注意しない限り、可能なunsigned値の半分が誤った動作になることを意味します。

正当な理由がないために変換する必要がある場合は、最初に値を保存する方法を再検討する必要があります。

編集: ProdigySimのコメントで述べたように、最大​​値はプラットフォームに依存します。ただし、INT_MAXおよびUINT_MAXを使用してアクセスできます。

通常の4バイトタイプの場合:

4 bytes = (4*8) bits = 32 bits

unsignedのように32ビットすべてが使用される場合、最大値は2 ^ 32-1、または4,294,967,295になります。

符号付きintは、符号用に1ビットを効率的に犠牲にするため、最大値は2 ^ 31-1、または2,147,483,647になります。これは他の値の半分であることに注意してください。

24
Chris Cooper

以下に示すように、unsigned intは、単純な式によって符号付き(またはその逆)に変換できます。

unsigned int z;
int y=5;
z= (unsigned int)y;   

質問の対象ではありませんが、次のリンクをお読みください:

4
sgokhales

変数unsigned int x;がある場合、(int)xを使用して、変数をintに変換できます。

2

次のように簡単です。

unsigned int foo;
int bar = 10;

foo = (unsigned int)bar;

またはその逆...

1
DarkDust

C++ Primer 5th 35ページ

範囲外の値を符号なしの型のオブジェクトに割り当てた場合、結果は、ターゲット型が保持できる値の数を法とする値の剰余になります。

たとえば、8ビットの符号なしcharは、0〜255の値を保持できます。範囲外の値を割り当てると、コンパイラはその値の残りを256を法として割り当てます。

unsigned char c = -1; // assuming 8-bit chars, c has value 255

範囲外の値をsigned型のオブジェクトに割り当てると、結果は未定義になります。プログラムが動作しているように見えたり、クラッシュしたり、ガベージ値が生成されたりする場合があります。

ページ160:オペランドが符号なしの型である場合、オペランドが変換される型は、マシン上の整数型の相対サイズに依存します。

...符号付きが異なり、符号なしオペランドの型が符号付きオペランドの型と同じかそれより大きい場合、符号付きオペランドは符号なしに変換されます。

残りのケースは、符号付きオペランドの型が符号なしオペランドよりも大きい場合です。この場合、結果はマシンに依存します。符号なし型のすべての値がラージ型に適合する場合、符号なしオペランドは符号付き型に変換されます。値が収まらない場合、符号付きオペランドは符号なしの型に変換されます。

たとえば、オペランドがlongおよびunsigned intであり、intとlongのサイズが同じ場合、長さはunsigned intに変換されます。 long型にさらにビットがある場合、unsigned intはlongに変換されます。

この本を読むことはとても助けになりました。

1
Jixuan Cheng

Unsigned intと(signed)intが同じ式で使用されている場合、signed intは暗黙的にunsignedに変換されます。これは、C言語のかなり危険な機能であるため、注意する必要があります。バグの原因である場合とそうでない場合があります。より詳細な回答が必要な場合は、コードを投稿する必要があります。

0
Lundin