int main(void)
{
unsigned int y = 10;
int x = – 4;
if (x > y)
Printf("x is greater");
else
Printf("y is greater");
getch();
return (0);
}
Output: x is greater
符号なしなので、出力はyの方が大きいと思いました。これの背後にある理由は何ですか?
int
値がunsigned int
にプロモートされるためです。特に、32ビットマシンでは0xFFFFFFFC
であり、unsigned int
は4294967292
であり、10
よりかなり大きい
C99 6.3.1.1-p2
Intが元の型のすべての値を表すことができる場合(ビットフィールドの幅によって制限される)、値はintに変換されます。それ以外の場合は、nsigned intに変換されます。これらは整数プロモーションと呼ばれます。他のすべてのタイプは、整数の昇格によって変更されません。
変換を実行するには:
C99 6.3.1.3-p2
それ以外の場合、新しいタイプが符号なしの場合、値が新しいタイプの範囲内になるまで、新しいタイプで表すことができる最大値よりも1だけ多く加算または減算することによって値が変換されます。
これは基本的に「UINT_MAX + 1を追加する」という意味です(とにかく読んでいます)。
プロモーションがunsigned int
側で行われた理由について。優先順位:
C99 6.3.1.8-p1
...それ以外の場合、符号なし整数型のオペランドのランクが他のオペランドの型のランク以上である場合、符号付き整数型のオペランドは、符号なし整数型のオペランドの型に変換されます。
それ以外の場合、符号付き整数型のオペランドの型が符号なし整数型のオペランドの型のすべての値を表すことができる場合、符号なし整数型のオペランドは符号付き整数型のオペランドの型に変換されます。
これは、int
とunsigned char
が期待どおりに機能することを示しています。
テスト
int main()
{
int x = -4;
unsigned int y = 10;
unsigned char z = 10;
if (x > y)
printf("x>y\n");
else
printf("x<y\n");
if (x > z)
printf("x>z\n");
else
printf("x<z\n");
return 0;
}
出力
x>y
x<z
それをよく見てください。
符号付き値と符号なし値の比較は、「符号なしスペース」で行われます。つまり、符号付きの値は、UINT_MAX + 1
を追加することで符号なしに変換されます。負の値に2の補数を使用する実装では、内部で値を特別に処理する必要はありません。
この例では、-4
は0x100000000-4
= 0xFFFFFFFC
に変換されます。これは明らかに> 10
です。
Cで2つの値を比較する場合、両方とも同じタイプである必要があります。この場合(int
およびunsigned int
)、最初にint
値がunsigned int
に変換されます。
次に、Cの符号なし整数演算は、その型の最大値+ 1を法として実行されます(つまり、「ループ」するため、UINT_MAX + 1
は0
になり、その逆も同様です)。したがって、負の値を符号なしに変換すると、非常に大きな数になります。
規格の関連セクションには次のように書かれています。
6.3.1.3符号付きおよび符号なし整数
2
それ以外の場合、新しいタイプが符号なしの場合、値が新しいタイプの範囲内になるまで、新しいタイプで表現できる最大値より1つ多い値を繰り返し加算または減算することにより、値が変換されます。
int
とunsigned int
を比較すると、int
はunsigned int
に変換されます。 int
からunsigned int
への変換は、UINT_MAX+1
を追加することによって行われます(int
は負であることに注意してください)。だから実際にあなたは比較しています:
if (-3 + UINT_MAX > 10) //Since -4 is converted to UINT_MAX+1-4
それは本当です。
Int値の最初のビットは、それが正か負かを定義するために使用されます。 (1 =負、0正)比較の前に、両方の変数がunsigned intにキャストされ、最初のビットの1が数値の一部として解釈されます。
このコードは正常に機能するはずです:
int main(void)
{
unsigned int y = 10;
int x = – 4;
if (x > (int) y)
Printf("x is greater");
else
Printf ("y is greater");
getch ( );
return (0);
}