web-dev-qa-db-ja.com

〜x +〜y ==〜(x + y)は常に偽ですか?

このコードは常にfalseと評価されますか?両方の変数は、2の補数の符号付き整数です。

~x + ~y == ~(x + y)

条件を満たす数があるはずです。 -50005000の間の数値をテストしてみましたが、同等にはなりませんでした。条件の解を見つける方程式を設定する方法はありますか?

一方をもう一方と交換すると、プログラムに陰湿なバグが発生しますか?

153
Steve

矛盾を避けるために、いくつかのxといくつかのy(mod 2n) そのような

_~(x+y) == ~x + ~y
_

2の補数*により、

_      -x == ~x + 1
<==>  -1 == ~x + x
_

この結果に注目して、

_      ~(x+y) == ~x + ~y
<==>  ~(x+y) + (x+y) == ~x + ~y + (x+y)
<==>  ~(x+y) + (x+y) == (~x + x) + (~y + y)
<==>  ~(x+y) + (x+y) == -1 + -1
<==>  ~(x+y) + (x+y) == -2
<==>  -1 == -2
_

したがって、矛盾。したがって、すべてのxおよびy(mod 2に対して~(x+y) != ~x + ~yn)。


* 1の補数演算を使用するマシンでは、すべてのxおよびyに対して等式が実際に成り立つことに注意してください。これは、自分の補数である_~x = -x_が原因です。したがって、~x + ~y == -x + -y == -(x+y) == ~(x+y)

237
Alex Lockwood

2の補数

vast大半のコンピューターでは、xが整数の場合、_-x_は_~x + 1_として表されます。同様に、~x == -(x + 1)。あなたの方程式でこの主張をすることは:

  • 〜x +〜y ==〜(x + y)
  • -(x + 1)+-(y + 1)=-((x + y)+ 1)
  • -x-y-2 = -x-y-1
  • -2 = -1

これは矛盾であるため、~x + ~y == ~(x + y)は常にfalseです。


とはいえ、Pedantsは、Cは2の補数を必要としないことを指摘するので、考慮しなければなりません...

補数

one'scomplement では、_-x_は単に_~x_として表されます。ゼロは特別なケースであり、すべて0の(_+0_)とすべて1の(_-0_)表現の両方がありますが、IIRC、Cには異なるビットパターンがある場合でも_+0 == -0_が必要です。これは問題になりません。 _~_を_-_に置き換えるだけです。

  • 〜x +〜y ==〜(x + y)
  • -x +(-y)=-(x + y)

これは、すべてのxおよびyに対してtrueです。

113
dan04

xy(IE。if x == 13これは1101ベース2では、最後のビット、1)次に、4つの可能なケースがあります。

x = 0、y = 0:

LHS:〜0 +〜0 => 1 + 1 => 10
RHS:〜(0 + 0)=>〜0 => 1

x = 0、y = 1:

LHS:〜0 +〜1 => 1 + 0 => 1
RHS:〜(0 + 1)=>〜1 => 0

x = 1、y = 0:

これは宿題なので、これはあなたにお任せします(ヒント:前と同じですが、xとyを入れ替えました)。

x = 1、y = 1:

これもあなたにお任せします。

可能な入力が与えられると、式の左辺と右辺で右端のビットが常に異なることを示すことができます。したがって、少なくともその1ビットが反転しているため、両側が等しくないことが証明されました。互いに。

32
Paulpro

ビット数がnの場合

~x = (2^n - 1) - x
~y = (2^n - 1) - y


~x + ~y = (2^n - 1) +(2^n - 1) - x - y =>  (2^n + (2^n - 1) - x - y ) - 1 => modulo: (2^n - 1) - x - y - 1.

さて、

 ~(x + y) = (2^n - 1) - (x + y) = (2^n - 1) - x - y.

したがって、それらは常に1の違いで等しくありません。

ヒント:

x + ~x = -1(mod 2n

質問の目標が(C仕様を読むスキルではなく)数学をテストすることであると仮定すると、これで答えが得られるはずです。

27
Mehrdad

1と2の両方(さらに42の場合もあります)で、これを証明できます。

~x + ~y == ~(x + a) + ~(y - a)

a = yそして、私たちは持っています:

~x + ~y == ~(x + y) + ~(y - y)

または:

~x + ~y == ~(x + y) + ~0

したがって、2の補数で~0 = -1、命題は偽です。

それを補完する~0 = 0、命題は真実です。

10
ypercubeᵀᴹ

デニスリッチーの本によると、Cはデフォルトでは2の補数を実装していません。したがって、あなたの質問は常に真実であるとは限りません。

7
user1457474

_MAX_INT_を_011111...111_で表されるintとする(ただし、ビット数が多い場合)。そうすれば、_~x + x = MAX_INT_と_~y + y = MAX_INT_がわかるので、_~x + ~y_と~(x + y)の違いは_1_であることが確実にわかります。

5
Adrian Monk

Cでは、2の補数を実装する必要はありません。ただし、符号なし整数には、同様のロジックが適用されます。このロジックでは、差異は常に1になります!

5
user1422551

もちろん、Cは2の補数表現を必要としないため、この動作は必要ありません。たとえば、~x = (2^n - 1) - x~y = (2^n - 1) - yはこの結果を取得します。

3
user1472392

ああ、基本的な離散数学!

チェックアウト De Morganの法則

~x & ~y == ~(x | y)

~x | ~y == ~(x & y)

ブール証明にとって非常に重要です!

0
David Kaczynski