このコードは常にfalseと評価されますか?両方の変数は、2の補数の符号付きintです。
~x + ~y == ~(x + y)
条件を満たす数があるはずだと思います。との間の数値をテストしてみましたが、同等には-5000
なりませんでした。5000
条件の解を見つけるための方程式を設定する方法はありますか?
一方を他方に交換すると、プログラムに潜行性のバグが発生しますか?
このコードは常にfalseと評価されますか?両方の変数は、2の補数の符号付きintです。
~x + ~y == ~(x + y)
条件を満たす数があるはずだと思います。との間の数値をテストしてみましたが、同等には-5000
なりませんでした。5000
条件の解を見つけるための方程式を設定する方法はありますか?
一方を他方に交換すると、プログラムに潜行性のバグが発生しますか?
矛盾のために、次のようなものがいくつか存在すると仮定しx
ますy
(mod 2 n)
~(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) != ~x + ~y
すべてx
とy
(mod 2 n)に対して。
x
* 1の補数演算を使用するマシンでは、実際にはすべてと。に等式が当てはまることに注意してくださいy
。これは、1の補数の下で~x = -x
。したがって、~x + ~y == -x + -y == -(x+y) == ~(x+y)
。
大部分のコンピューターでは、 が整数の場合、x
は-x
として表され~x + 1
ます。同等に、~x == -(x + 1)
. 方程式でこの代入を行うと、次のようになります。
これは矛盾しているため、~x + ~y == ~(x + y)
常にfalseです。
そうは言っても、衒学者は、C は 2 の補数を必要としないので、考慮しなければならないことを指摘するでしょう...
の補数では、-x
は単に として表され~x
ます。ゼロは特殊なケースで、すべて 0 の ( +0
) とすべて 1 の ( -0
) 表現の両方がありますが、IIRC、C では+0 == -0
ビット パターンが異なっていても必要なので、これは問題になりません。~
に置き換えるだけ-
です。
これはすべてのとに当てはまります。x
y
x
両方の右端のビットのみを考えy
ます (つまり、x == 13
どちらが1101
基数 2 の場合は、最後のビット a のみを調べます1
)。次に、4 つのケースが考えられます。
x = 0、y = 0:
左側: ~0 + ~0 => 1 + 1 => 10
右側: ~(0 + 0) => ~0 => 1
x = 0、y = 1:
左側: ~0 + ~1 => 1 + 0 => 1
右側: ~(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 2 n )
質問の目的が (C 仕様を読むスキルではなく) 数学をテストすることであると仮定すると、これで答えが得られるはずです。
1 の補数でも 2 の補数でも (さらには 42 の補数でも)、これは次のように証明できます。
~x + ~y == ~(x + a) + ~(y - a)
それでは、次のようa = y
にします。
~x + ~y == ~(x + y) + ~(y - y)
また:
~x + ~y == ~(x + y) + ~0
したがって、2 の補数 that~0 = -1
では、命題は偽です。
の補数で~0 = 0
は、命題は真です。
Dennis Ritchie の著書によると、C はデフォルトで 2 の補数を実装していません。したがって、あなたの質問が常に正しいとは限りません。
で表さMAX_INT
れる int とします011111...111
(ただし、ビット数が多い場合)。次に、 と を知っているので、~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
はこの結果を取得します。