与えられた 3 つの数値の提案された解決策として、それらの 2 番目に大きいものを見つけてください、私は書きました:
int second_largest(int a, int b, int c) {
int smallest = min(min(a, b), c);
int largest = max(max(a, b), c);
/* Toss all three numbers into a bag, then exclude the
minimum and the maximum */
return a ^ b ^ c ^ smallest ^ largest;
}
アイデアは^ smallest ^ largest
、中間の数が残るようにビットをキャンセルすることです。
ただし、@chux は問題を指摘しました。
int
andの特異な問題a ^ b ^ c ^ smallest ^ largest
は、まれな非 2 の補数プラットフォームで中間結果がトラップ表現になる可能性があることです。– チュークス@chux説明してください?XOR はビットごとに動作するだけで、ビットが何を表しているかは気にしませんよね? – 200_成功
XOR は気にしませんが、結果が問題になる可能性があります。たとえば、符号と絶対値の整数の場合、トラップ値が発生してコードが停止する可能性があります
-1 ^ 1
。-0
C11 §6.2.6.2 を参照してください。– チュークスさらに、C11 §6.2.6.2 3 では、まれな非 2 の補数プラットフォームでの int を使用した ^ の実装定義の動作を指定しています。特に、「これらのケースが実際に負のゼロまたは通常のゼロを生成するかどうかは指定されていません」 ^ b ^ c ^ 最小 ^ 最大の未指定をレンダリングすると、トラップ値が使用されていない場合でも、必要に応じて機能します。次のセクションでは、これが UB になる方法について説明します。この斬新なコードは unsigned 型に任せるのが最善です。– チュークス
論理的にも数学的にも正しいはずの技術が、専門性によって狂ってしまうのは残念なことです。
この XOR 手法を救済し、法的に安全にする方法はありますか? (組合が絡むものかな?)