3

2つのunsignedintを減算し、その結果をsigned int(またはリテラル)と比較しようとしています。unsigned intタイプを使用する場合、動作は期待どおりです。uint16_t(from )型を使用する場合stdint.h、動作は私が期待するものではありません。比較はgcc4.5を使用して行われました。
次のコードが与えられます:

unsigned int a;
unsigned int b;

a = 5;
b = 20;

printf("%u\n", (a-b) < 10);

出力は0で、これは私が期待したものです。aとbはどちらも符号なしであり、bはaより大きいため、結果は10より大きい大きな符号なしの数値になります。aとbをuint16_tと入力すると、次のようになります。

uint16_t a;
uint16_t b;

a = 5;
b = 20;

printf("%u\n", (a-b) < 10);

出力は1です。これはなぜですか?2つのuint16_tタイプ間の減算の結果は、gccのintに格納されていますか?をに変更する1010U、出力は再び0になります。これは、これをサポートしているようです(減算結果がintとして格納され、符号なしintと比較される場合、減算結果は符号なしintに変換されます)。

4

2 に答える 2

7

int / unsigned int(char、short、unsigned shortなど、ただしlong、unsigned longなど)より下の型では計算が行われないため、最初にintまたはunsignedintのいずれかにプロモートされます。「uint16_t」は、実装では「unsigned short」である可能性があり、実装では「int」にプロモートされます。したがって、その計算の結果は「-15」であり、これは10よりも小さくなります。

16ビットで計算する古い実装では、両方のビット幅が同じであるため、「int」は「unsignedshort」のすべての値を表すことができない場合があります。このような実装では、「unsignedshort」を「unsignedint」に昇格させる必要があります。このような実装では、比較の結果は「0」になります。

于 2012-04-06T18:59:34.813 に答える
5

-と演算の両方が実行される前に、通常の算術変換<と呼ばれる一連の変換が適用され、オペランドが共通の型に変換されます。このプロセスの一部として、整数昇格が適用されます。整数昇格は、これら2つのタイプのいずれかよりも狭いタイプまたは1つに昇格します。intunsigned int

最初のケースでは、とのタイプはabあるため、演算子unsigned intによるタイプの変更は発生しません。結果は、大きな正の値を持つになります。次に、とは同じランクであるため、タイプの値はに変換され、比較が実行されて値がになります。-unsigned intUINT_MAX - 14intunsigned int10intunsigned int0

int2番目のケースでは、実装で型が型のすべての値を保持できることは明らかですuint16_t。これは、整数の昇格が適用されると、との値がaタイプbに昇格されることを意味しますint。減算が実行され、-15タイプが。の値になりますint。の両方のオペランド<はすでにintであるため、変換は実行されません。の結果は<です1

10U後者の場合にaを使用すると、の結果a - bは引き続き-15タイプになりintます。ただし、通常の算術変換では、この値がunsigned int10最初の例の場合と同様に)に変換され、その結果、値がUINT_MAX - 14;になります。の結果は<です0

于 2012-04-07T12:36:00.187 に答える