2
#include "stdio.h"

int main()
{
    int x = -13701;
    unsigned int y = 3;
    signed short z = x / y;

    printf("z = %d\n", z);

    return 0;
}

答えは -4567 になると思います。「z = 17278」を取得しています。これらの数値を昇格すると 17278 になるのはなぜですか?

これをCode Padで実行しました。

4

4 に答える 4

11

非表示の型変換は次のとおりです。

signed short z = (signed short) (((unsigned int) x) / y);

署名された型と署名されていない型を混在させると、署名されていない型が優先されます。xに変換されunsigned int、3 で除算され、その結果が (signed) にダウンコンバートされshortます。32 ビット整数の場合:

(unsigned) -13701         == (unsigned) 0xFFFFCA7B // Bit pattern
(unsigned) 0xFFFFCA7B     == (unsigned) 4294953595 // Re-interpret as unsigned
(unsigned) 4294953595 / 3 == (unsigned) 1431651198 // Divide by 3
(unsigned) 1431651198     == (unsigned) 0x5555437E // Bit pattern of that result
(short) 0x5555437E        == (short) 0x437E        // Strip high 16 bits
(short) 0x437E            == (short) 17278         // Re-interpret as short

ちなみにsignedキーワードは不要です。signed shortは長い言い方ですshort。明示を必要とする唯一の型signedchar. charプラットフォームに応じて、署名付きまたは未署名にすることができます。他のすべてのタイプは、デフォルトで常に署名されています。

于 2010-09-23T15:27:33.067 に答える
4

短い答え: 師団は最初に に昇格xunsignedます。その場合にのみ、結果が にキャストされますsigned short

長い答え:この SO スレッドを読んでください。

于 2010-09-23T15:26:16.567 に答える
3

問題はunsigned int y. 確かに、x/y無署名になります。それはで動作します:

#include "stdio.h"

int main()
{
    int x = -13701;
    signed int y = 3;
    signed short z = x / y;

    printf("z = %d\n", z);

    return 0;
}
于 2010-09-23T15:27:31.697 に答える
1

加算および乗算算術演算で「大きな」符号付き値と符号なし値を混合するたびに、符号なし型が「勝ち」、評価は符号なし型の領域で実行されます (「大きな」とはint、より大きいことを意味します)。元の符号付きの値が負の場合、符号付きから符号なしへの変換の規則に従って、最初に符号なしの正の値に変換されます。あなたの場合-13701は にUINT_MAX + 1 - 13701なり、結果は配当として使用されます。

一般的な 32 ビットintプラットフォームでの符号付きから符号なしへの変換の結果は、符号なしの値になることに注意してください4294953595。で除算する3と、 が得られます1431651198shortこの値は、16 ビットshort型のプラットフォームで強制的にオブジェクトにするには大きすぎます。それを行おうとすると、実装定義の動作が発生します。したがって、プラットフォームのプロパティが私の仮定と同じである場合、コードは実装定義の動作を生成します。正式に言えば、得られる「無意味な」17278値は、その実装定義の動作の特定の現れにすぎません。オーバーフロー チェックを有効にしてコードをコンパイルした場合 (コンパイラがサポートしている場合)、代入でトラップされる可能性があります。

于 2010-09-23T16:19:40.300 に答える