short
質問に記載されているように、 16 ビットと 32ビットを想定していますint
。
unsigned short a = 0xFFFF;
これは、またはに初期化a
されます。式の型は; 暗黙的に に変換され、値は保持されます。0xFFFF
65535
0xFFFF
int
unsigned 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 はこの場合のルールを追加し、代わりに実装定義のシグナルを発生させることを許可しました。これを行うコンパイラは知りません。)