この複合形式を使用した場合、XORによる値のスワップはなぜ失敗するのでしょうか?
2023-08-09 18:44:24
質問
XORを使用して、第3の変数を使用せずに2つの数値を交換するために、次のコードを発見しました。
^
演算子を使用しています。
コードです。
int i = 25;
int j = 36;
j ^= i;
i ^= j;
j ^= i;
Console.WriteLine("i:" + i + " j:" + j);
//numbers Swapped correctly
//Output: i:36 j:25
さて、上記のコードをこのような等価なコードに変更しました。
私のコードです。
int i = 25;
int j = 36;
j ^= i ^= j ^= i; // I have changed to this equivalent (???).
Console.WriteLine("i:" + i + " j:" + j);
//Not Swapped correctly
//Output: i:36 j:0
今、知りたいのは なぜ私のコードは不正確な出力をするのでしょうか?
どのように解決するのですか?
編集部:わかりました。
最初のポイントは、明らかにこのコードはとにかく使うべきでないということです。しかし、これを展開すると、次のように等価になります。
j = j ^ (i = i ^ (j = j ^ i));
(のような複雑な表現を用いる場合、そのような表現が可能です。
foo.bar++ ^= i
のような複雑な式を使う場合は
++
が一度だけ評価されることが重要ですが、ここではよりシンプルに考えています)。
さて、オペランドの評価順序は常に左から右なので、まず、次のようになります。
j = 36 ^ (i = i ^ (j = j ^ i));
これ(上記)が最も重要なステップです。
最後に実行されるXOR演算のLHSが36になってしまっていますね。LHS は "の値ではありません。
j
の値ではありません。
のRHSの評価には、"1レベルの入れ子"式が含まれるので、次のようになります。
j = 36 ^ (i = 25 ^ (j = j ^ i));
次に、最も深いレベルの入れ子に注目すると、両方の
i
と
j
:
j = 36 ^ (i = 25 ^ (j = 25 ^ 36));
... これは
j = 36 ^ (i = 25 ^ (j = 61));
への代入は
j
への代入が最初に起こりますが、結果は最後に上書きされるので、それを無視することができます。
j
の更なる評価はありません。
j = 36 ^ (i = 25 ^ 61);
と同等になりました。
i = 25 ^ 61;
j = 36 ^ (i = 25 ^ 61);
または
i = 36;
j = 36 ^ 36;
となる。
i = 36;
j = 0;
I を考える はすべて正しく、正しい答えにたどり着きます。評価の順番に関する詳細が少しずれていたら、Eric Lippertに謝罪します :(
関連
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】Visual Studio: 操作を完了できませんでした。パラメータが正しくありません
-
[解決済み】OnCollisionEnter2Dが実行されない?
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?
-
[解決済み】Microsoft.Extensions.LoggingからILoggerを解決することができない
-
[解決済み] NULL-COALESCING 演算子のカスタム暗黙変換の不思議な挙動
-
[解決済み] C#で演算子==はジェネリック型に適用できない?
-
[解決済み】三項演算子はif-elseブロックの2倍遅い?
-
[解決済み] Pythonのスワッピングを理解する:なぜa, b = b, aとb, a = a, bは必ずしも等価ではないのですか?
-
[解決済み] なぜ、ハッシュを組み合わせるのにXORがデフォルトなのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み】C#で四捨五入する方法
-
[解決済み】Excel "外部テーブルが期待された形式ではありません。"
-
[解決済み】"The ConnectionString property has not been initialized "を修正する方法
-
[解決済み】プロジェクトビルド時のエラー。エディタでスクリプトにコンパイルエラーがあるため、Playerのビルドにエラーが発生する
-
[解決済み】ORA-01008: すべての変数がバインドされていません。これらはバインドされています。
-
[解決済み】Entity FrameworkからのSqlException - セッション内で他のスレッドが動作しているため、新しいトランザクションは許可されません。
-
[解決済み】「...は'型'であり、与えられたコンテキストでは有効ではありません」を解決するにはどうすればよいですか?(C#)
-
[解決済み】「namespace」なのに「type」のように使われる。
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。