このコードは常にfalseと評価されますか?どちらの変数も2の補数の符号付き整数です。
~x + ~y == ~(x + y)
条件を満たす数はあるはずだと思います。私は間の数字をテストしようとした-5000
と5000
が、平等を達成したことがありません。条件の解を見つけるための方程式を設定する方法はありますか?
片方をもう片方に交換すると、プログラムに潜むバグが発生しますか?
true
厳密な2の補数を仮定できない場合でも、戻ることができます。
このコードは常にfalseと評価されますか?どちらの変数も2の補数の符号付き整数です。
~x + ~y == ~(x + y)
条件を満たす数はあるはずだと思います。私は間の数字をテストしようとした-5000
と5000
が、平等を達成したことがありません。条件の解を見つけるための方程式を設定する方法はありますか?
片方をもう片方に交換すると、プログラムに潜むバグが発生しますか?
true
厳密な2の補数を仮定できない場合でも、戻ることができます。
回答:
矛盾があるため、次のような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
and y
(mod 2 n)についてです。
*興味深いのは、1の補数演算を備えたマシンでは、等式は実際にはすべてのx
およびに当てはまるということですy
。これは、補数の下にあるため~x = -x
です。したがって、~x + ~y == -x + -y == -(x+y) == ~(x+y)
。
~x == -(x+1)
、~(x+y) == ~x + ~y
-(x+y+1) == -(x+1) + -(y+1)
-1 == -2
上の広大な場合は、コンピュータの大多数、x
整数であり、その後、-x
として表されます~x + 1
。等価的に、~x == -(x + 1)
。方程式でこのサブスチューデントを作成すると、次のようになります。
これは矛盾なので~x + ~y == ~(x + y)
、常にfalseです。
とは言っても、Cは2の補数を必要としないことをペダントは指摘するので、我々も考慮しなければなりません...
で1の補数、-x
単にとして表現されます~x
。ゼロはすべて0の(+0
)とすべて1の(-0
)の両方の表現を持つ特殊なケースですが、IIRC、Cでは+0 == -0
ビットパターンが異なっていても必要なので、これは問題になりません。で置き換え~
てください-
。
これは真のすべてのためにx
とy
。
+0 == -0
. 最後に、Cで意味のあるもの:)
両方の唯一の右端のビットを考えるx
とy
(IE場合。x == 13
これは1101
ベース2に、我々は唯一の、最後のビットを見ていきます1
)そして、四つの可能なケースがあります。
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 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の補数で~0 = -1
は、命題は誤りです。
それを補完するもの~0 = 0
として、命題は真実です。
Dennis Ritchieの本によると、Cはデフォルトで2の補数を実装していません。したがって、あなたの質問は必ずしも正しいとは限りません。
Cは、2の補数が実装されているものである必要はありません。ただし、符号なし整数については、同様のロジックが適用されます。このロジックでは、差異は常に1になります。
もちろん、Cは2の補数表現を必要としないため、この動作を必要としません。たとえば、~x = (2^n - 1) - x
&~y = (2^n - 1) - y
はこの結果を取得します。