6

次のコードを実行しようとしていますが、ここで何が起こっているのか混乱しています。

int main()
{
 /* 
    a = -1; 
    b = 0xffffffff; 
 */
if(-1 == 0xffffffff )
        printf("-1 is equal to maximum\n");
else
        printf(" -1 is not equal to maximum\n");

if(0xff < -1)
        printf(" Less than -1 \n");
if(0xff < 0xffffffff)
        printf(" Less than maximum\n");

コメント付きのセクションも試してみて、-1を「a」に、0xffffffffを「b」に置き換えましたが、結果は同じです。

32ビットシステムなので、整数サイズの4バイトを使用しました。

私の出力は:

-1 is equal to maximum
 Less than maximum

-1がmaximumに等しい場合、最後の2つのifステートメントの両方を実行する必要があります。しかし、それは起こっていません。なんで?

4

4 に答える 4

5

これをC++から引用します。Cも同じだと思います。

リテラル-1は常にsigned intです。

リテラル0xffはですsigned int0xffffffffunsigned intです。

混合符号の比較では、両方のオペランドが符号なしに変換され、すべての結果が説明されます。

C ++ 11の表6の裸の整数リテラル(つまり、型接尾辞なし)の型に関する規則は次のとおりです。

  • 10進リテラルは、、またはのいずれか適切な方の中intで最小のタイプです。long intlong long int

  • 16進リテラルは、、、、、、、のいずれか該当する方の中で最小のタイプintです。unsigned intlong intunsigned long intlong long intunsigned long long int

もう一度詳しく説明するには:

  • 最初の比較では、両側がに変換されunsigned int、値が得られます0xFFFFFFFF

  • 2番目の比較では、両方の項は符号付き整数であり、左の項は255であり、右の項は-1です。

  • 3番目の比較では、両方の項がに変換されunsigned intます。


この質問の署名のハードウェア実装について心配する必要がないことに注意してください。プラットフォームに依存する唯一の関連する値は、のサイズです。これは、に適合しないが、に適合するとint主張したときに使用しました。0xffffffffintunsigned int

于 2012-09-10T12:04:02.697 に答える
3

C / C ++では、負の数は2の補数形式で格納され、最上位ビット(MSB)はため息の表示として機能します。

MSB 1は-veを意味し、MSB0は+veを意味します。1xxxxxxxxxxは-ve番号で、0xxxxxxxxxxは+veを意味します。1xxxxxxxでは、「xxxxxx」は2の数字の補数です。また、0xxxxxxでは、「xxxxx」は数値の実際の2進表現です。

コンパイラは、MSB(符号ビット)が1の場合、数値を-veとして解釈し、数値が2の補数でなければならないことを理解します。

まず、2の褒め言葉を見てみましょう。

2の褒め言葉は、実際の数(すべてのビット)を否定してから1を加算することです。

10進数1=00000001

〜10進数1 = 11111110

2の10進数の補数1=11111111(F hex)

したがって、-1は= (1) 111111111111111になります

(1)は-veの数値を示すMSBであり、残りは数値の2の補数です。

したがって、-1 = 0xFFFFFFFF

いくつかの-ve数値の2進表現を印刷して、数値の2進表現の2の補数を比較してみることができます。

于 2014-11-11T07:51:55.213 に答える
0

0xffffffffタイプには4バイトしかなく、の2の補数はメモリ( )にある-1ため、はに等しくなります。したがって、コンパイラには区別する方法がありません。メモリ内にそのための余地がないだけです。int-10xffffffff-1 == (~1) + 1-10xffffffff

0x000000ff255はより大きいと同等である-1ため、最後の2つifは実行されません。

あなたを混乱させるかもしれないものはこれです:

char c = 0xff;
if( c == -1 ) {
     printf("char 0xff is -1");
}

この場合、acharとを比較するintので、コンパイラは8ビットchar型を拡張する必要があります。が署名されているためchar、署名(最上部のビット)が保持され、-1(int)が取得されます。

コードパッドでのインタラクティブなデモ

これは、符号付き/符号なしタイプと異なる幅のタイプを混在させるときに注意が必要な理由の例です。

于 2012-09-10T12:06:06.530 に答える
0

まず、表示される結果は、符号付き整数のビット表現とは関係ありませんが、サイズとは関係があります。

符号なしに変換すると、値-1は宛先タイプの最大値に変換されます。だから-1 == 0xffffffffです。のビット表現は-1何にも影響しません。

0xff < -1両方の値が符号付きであるため、はfalseですint。左側が255、右側が-1です。

最後に、最初の比較で-1がunsignedに変換される理由は、実装では(そしてほとんどの実装で0xffffffffは)大きすぎるためです。ただし、これは(実装、および16ビットマシン以外のほとんどの実装に)適合します。unsignedintをsignedintと比較するために、Cはsignedintをunsignedに変換します。これにより、驚くべき結果が得られます(-1が正の数に等しいという驚きを含む)。そのため、ほとんどのスタイルガイドでは、符号付きタイプと符号なしタイプの混合を避けるように指示されています。しかし、言語を変更するには遅すぎます。int unsigned int

于 2012-09-10T12:14:40.313 に答える