short質問に記載されているように、 16 ビットと 32ビットを想定していますint。
unsigned short a = 0xFFFF;
これは、またはに初期化aされます。式の型は; 暗黙的に に変換され、値は保持されます。0xFFFF655350xFFFFintunsigned short
signed short b = 0xFFFF;
これはもう少し複雑です。繰り返します0xFFFFが、タイプはintです。--に暗黙的に変換されsigned shortますが、値が変換の範囲外であるため、値をsigned short保持できません。
値を表すことができない場合、整数を符号付き整数型に変換すると、実装定義の値が生成されます。原則として、 の値はから までbの間の任意の値になり-32768ます+32767。実際には、ほぼ確実に-1. これ以降は、値が であると仮定します-1。
unsigned int u16tou32 = a;
の値aは0xFFFF、 から に変換さunsigned shortれunsigned intます。変換は値を保持します。
unsigned int s16tou32 = b;
の値はbです-1。に変換されますがunsigned int、これは明らかに の値を格納できません-1。整数から符号なし整数型への変換 (符号付き型への変換とは異なります) は、言語によって定義されます。結果は moduloMAX + 1で縮小されます。ここMAXで、 は unsigned 型の最大値です。この場合、 に格納される値s16tou32はUINT_MAX - 1、または0xFFFFFFFFです。
signed int u16tos32 = a;
a、 、の値0xFFFFは に変換されsigned intます。値は保持されます。
signed int s16tos32 = b;
b、 、の値-1は に変換されsigned intます。値は保持されます。
したがって、保存された値は次のとおりです。
a == 0xFFFF (65535)
b == -1 (not guaranteed, but very likely)
u16tou32 == 0xFFFF (65535)
s16tou32 == 0xFFFFFFFF (4294967295)
u16tos32 == 0xFFFF (65535)
s16tos32 == -1
整数変換規則を要約すると、次のようになります。
ターゲットの型が値を表すことができる場合、値は保持されます。
それ以外の場合、ターゲットの型が unsigned の場合、値は moduloMAX+1で減らされます。これは、下位 N ビットを除くすべてを破棄することと同じです。これを説明する別の方法はMAX+1、範囲内の結果が得られるまで、値が値に繰り返し加算または値から減算されることです (これは、実際に C 標準で説明されている方法です)。コンパイラは、この繰り返し加算または減算を行うコードを実際には生成しません。彼らはただ正しい結果を得なければなりません。
それ以外の場合、ターゲットの型は署名されており、値を表すことができません。変換により、実装定義の値が生成されます。ほとんどすべての実装で、結果は 2 の補数表現を使用して下位 N ビットを除くすべてを破棄します。(C99 はこの場合のルールを追加し、代わりに実装定義のシグナルを発生させることを許可しました。これを行うコンパイラは知りません。)