7

私が使用する言語は C です。x と n の型は int です。

次のような1行のコードがあります

  printf("x=%x,n=%d,first=%x,second=%x\n",x,n,((~(x+0xffffffff))>>n),((~x+1)>>n));

x,n の値と、x の補数の n ビットをシフトする 2 つの方法を示します。x=0x80000000,~(x+0xffffffff)=0x8000000,~x+1=0x80000000のとき、この2つをnビットシフトすると結果が異なります。

ところで、0xffffffff を ~1+1 (つまり ~(x+(~1+1))) に変更すると、結果は ~x+1 と同じになります。

なぜそうなったのだろうか。ありがとう。

4

3 に答える 3

4

intPavan Manjunath による現在削除された回答には、通常どおり 32 ビット型であると仮定して、1 つのケースに対して正しい回答がありました。整数定数

0xffffffff

には値が2^32 - 1あり、 では表現できませんintが、 として表現できunsigned intます。したがって、その型はunsigned int(6.4.4.1) です。したがって、 は加算用にx変換され、unsigned int

((~(x+0xffffffff))>>n)

として評価します

((~(0x80000000u + 0xffffffffu)) >> n)
((~0x7fffffffu) >> n)
(0x80000000u >> n)

2^(31-n)if 0 <= n < 32(がその範囲外の場合nは未定義の動作です)。

がでx = 0x80000000ある場合、ouah の答えは正しく、int符号付き整数のオーバーフローとして未定義の動作です。~0x8000000 = 0x7fffffff = INT_MAXINT_MAX + 1

それにもかかわらず、一般的な動作はラップアラウンドであり、加算の結果は符号付き整数0x80000000であり、負の整数の右シフトは実装定義の動作です (6.5.7)。一般的なのは、符号拡張を使用してシフトすることです。これにより、結果が生成され、変換指定子によって値を使用して-2^(31-n)解釈されます。unsigned int2^32 - 2^(31-n)printf%x

于 2012-06-04T14:23:49.900 に答える
1

x=0x80000000の場合、~(x+0xffffffff)=0x8000000、~x+1=0x80000000、

32 ビット(がタイプであるとint仮定) および 2 の補数の符号付き表現を持つシステムでは、次の式:xint

 ~x+1

未定義の動作です。未定義の動作x = 0x80000000を意味~x == 0x7FFFFFFF == INT_MAXします。INT_MAX + 1そう~x + 1かもしれ0x80000000ませんし、他の何かかもしれません。

この式:

~(x+0xffffffff)

一方、 は定義されており (0xffffffffunsigned intC にあります)、 は に等しくなり0x80000000ます。0xffffffffisunsigned intと unsigned integer は C 標準の意味でオーバーフローしないため、実際に定義されています。

これは、次のステートメントを意味します。

printf("x=%x,n=%d,first=%x,second=%x\n",x,n,((~(x+0xffffffff))>>n),((~x+1)>>n));

未定義の動作を引き起こし、両方の結果を比較しても意味がありません。

于 2012-06-04T14:02:09.357 に答える
0

(sizeof(int) が 4、つまり 32 ビット符号付きの値であると仮定します)。0x80000000; // -2147483648 可能な最小の負の整数 0xFFFFFFFF // は -1

2 つを一緒に追加すると、負から正への「ラップアラウンド」が発生します。

0x7FFFFFFF で「~」演算子を使用すると、ビット単位の完全な結果、つまり 0x80000000 が生成されます。

任意の int 値から始めて、十分な回数 1 を減算 (または 1 を加算しても問題ありません) すると、符号が反転します。これは、固定精度を使用した算術演算の基本的な問題です。

あなたの場合、この限定的なケースに十分注意せずに、符号付き算術演算子とビット演算子を混在させることは期待できません。

また、2 の補数演算を使用する場合、非対称性があることに注意してください。正の数よりも負の数が 1 つ多くなります (ゼロを表す必要があるため、残りの値に対して奇数の他のビット表現が残ります)。

于 2012-06-04T14:23:00.853 に答える