7

Cで次のコードを実行すると:

#include <stdint.h>

uint16_t a = 4000;
uint16_t b = 8000;

int32_t c = a - b;

printf("%d", c);

結果として「-4000」が正しく出力されます。しかし、私は少し混乱しています。より大きな符号なし整数を他の整数から減算すると、算術オーバーフローが発生するのではないでしょうか? ここではどのようなキャスティング ルールが適用されますか? この質問は少し初心者のようですので、参考にしていただければ幸いです。

4

4 に答える 4

5

この問題は実際にはやや複雑です。算術式のオペランドは、標準 (C89)のセクション 3.2.1.5 で確認できる特定の規則を使用して変換されます。あなたの場合、答えはタイプによって異なりますuint16_t。より小さい場合int、たとえばshort intの場合、オペランドは に変換されint、-4000 が返されますが、16 ビット システムでuint16_tは可能でunsigned intあり、符号付き型への変換は自動的には行われません。

于 2009-04-08T07:40:36.650 に答える
3

int簡単な答えは、これらはすべて減算中に昇格されるということです。長い答えについては、C 標準のセクション 6.3.1.1 を見てください。ここでは、算術式での整数の昇格について説明しています。標準の関連言語:

intが元の型のすべての値を表すことができる場合、値はint;に変換されます。それ以外の場合は、に変換されますunsigned int。これらは整数プロモーションと呼ばれます。他のすべての型は、整数の昇格によって変更されません。

詳細もそこにありますが、かなり厄介になります。

于 2009-04-08T07:35:55.633 に答える
1

int32_t両方のオペランドは、減算中に昇格されます。結果が最大値よりも大きかった場合、int32_tオーバーフローが発生します。

于 2009-04-08T07:20:36.480 に答える
0

実際、オーバーフローがありますが、C ではわかりません。

オーバーフローにより、符号付き整数として解釈されるとたまたま -4000 になる値が残ります。これは、2 の補数マシンで設計どおりに機能します。

結果を符号なしとして解釈してみると、u1 < u2 の場合、(u1-u2) が一見無関係な数値に評価されることがわかります。

于 2009-04-08T07:56:02.167 に答える