8

私は本Computer Systems: A Programmer's Perspective, 2/Eで次のコードを見たことがあります。これはうまく機能し、目的の出力を作成します。出力は、符号付き表現と符号なし表現の違いによって説明できます。

#include<stdio.h>
int main() {
    if (-1 < 0u) {
        printf("-1 < 0u\n");
    }
    else {
        printf("-1 >= 0u\n");
    }
    return 0;
}

上記のコードは を生成-1 >= 0uしますが、上記と同じである次のコードは生成しません! 言い換えると、

#include <stdio.h>

int main() {

    unsigned short u = 0u;
    short x = -1;
    if (x < u)
        printf("-1 < 0u\n");
    else
        printf("-1 >= 0u\n");
    return 0;
}

利回り-1 < 0u。なぜこれが起こったのですか?これは説明できません。

このような同様の質問を見たことがありますが、役に立たないことに注意してください。

PS。@Abhineetが言ったように、ジレンマはに変更shortすることで解決できますint。しかし、この現象をどのように説明できるでしょうか。つまり、-14 バイトでは0xff ff ff ff、2 バイトでは0xff ffです。として解釈される 2 の補数としてそれらを考えるとunsigned、それらは と の対応する値を4294967295持ち65535ます。どちらも 未満ではなく、どちらの場合も、出力は、つまり で0ある必要があると思います。-1 >= 0ux >= u

リトルエンディアン Intel システムでの出力例:

略して:

-1 < 0u
u =
 00 00
x =
 ff ff

int の場合:

-1 >= 0u
u =
 00 00 00 00
x =
 ff ff ff ff
4

4 に答える 4

3

C の整数昇格規則に遭遇しています。

より小さい型の演算子は、オペランドをorintに自動的に昇格させます。詳細な説明については、コメントを参照してください。その後も型が一致しない場合 (例: unsigned int と int)、2 項 (2 オペランド) 演算子には次のステップがあります。ルールをこれ以上詳しく要約するつもりはありません。 Lundin's answer を参照してくださいintunsigned int

このブログ投稿では、署名済みおよび署名なしの char と同様の例で、これについて詳しく説明しています。C99 仕様を引用します。

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


ゴッドボルトのようなもので、 one または zero を返す関数を使用して、これをより簡単に試すことができます。コンパイラの出力を見て、最終的に何が起こっているかを確認してください。

#define mytype short

int main() {
    unsigned mytype u = 0u;
    mytype x = -1;
    return (x < u);
}
于 2015-10-26T07:05:53.753 に答える
0

0uありませんunsigned short、ありunsigned intます。

編集::動作の説明、 比較はどのように行われますか?

Jens Gustedt の回答によると、

これは、標準では「通常の算術変換」と呼ばれ、同じ演算子のオペランドとして 2 つの異なる整数型が発生するたびに適用されます。

本質的には何ですか

型の幅が異なる場合 (より正確には、標準が変換ランクと呼ぶもの)、両方の型が同じ幅である場合、より広い型に変換されます。本当に奇妙なアーキテクチャに加えて、それらの符号なしが勝ちます。値 -1 の符号付きから符号なしへの変換どのような型でも、符号なし型の表現可能な最大値が常に得られます。

彼が書いたより説明的なブログはここにあります。

于 2015-10-26T06:58:03.807 に答える