このコードは常にfalseと評価されますか?両方の変数は、2の補数の符号付き整数です。
~x + ~y == ~(x + y)
条件を満たす数があるはずです。 -5000
と5000
の間の数値をテストしてみましたが、同等にはなりませんでした。条件の解を見つける方程式を設定する方法はありますか?
一方をもう一方と交換すると、プログラムに陰湿なバグが発生しますか?
矛盾を避けるために、いくつかの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 + ~y
n)。
* 1の補数演算を使用するマシンでは、すべてのx
およびy
に対して等式が実際に成り立つことに注意してください。これは、自分の補数である_~x = -x
_が原因です。したがって、~x + ~y == -x + -y == -(x+y) == ~(x+y)
。
vast大半のコンピューターでは、x
が整数の場合、_-x
_は_~x + 1
_として表されます。同様に、~x == -(x + 1)
。あなたの方程式でこの主張をすることは:
これは矛盾であるため、~x + ~y == ~(x + y)
は常にfalseです。
とはいえ、Pedantsは、Cは2の補数を必要としないことを指摘するので、考慮しなければなりません...
one'scomplement では、_-x
_は単に_~x
_として表されます。ゼロは特別なケースであり、すべて0の(_+0
_)とすべて1の(_-0
_)表現の両方がありますが、IIRC、Cには異なるビットパターンがある場合でも_+0 == -0
_が必要です。これは問題になりません。 _~
_を_-
_に置き換えるだけです。
これは、すべてのx
およびy
に対してtrueです。
x
とy
(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ビットが反転しているため、両側が等しくないことが証明されました。互いに。
ビット数が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仕様を読むスキルではなく)数学をテストすることであると仮定すると、これで答えが得られるはずです。
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
、命題は真実です。
デニスリッチーの本によると、Cはデフォルトでは2の補数を実装していません。したがって、あなたの質問は常に真実であるとは限りません。
_MAX_INT
_を_011111...111
_で表されるintとする(ただし、ビット数が多い場合)。そうすれば、_~x + x = MAX_INT
_と_~y + y = MAX_INT
_がわかるので、_~x + ~y
_と~(x + y)
の違いは_1
_であることが確実にわかります。
Cでは、2の補数を実装する必要はありません。ただし、符号なし整数には、同様のロジックが適用されます。このロジックでは、差異は常に1になります!
もちろん、Cは2の補数表現を必要としないため、この動作は必要ありません。たとえば、~x = (2^n - 1) - x
&~y = (2^n - 1) - y
はこの結果を取得します。