この質問は、Cracking the Coding のインタビュー本で見ました。
問題を「言い換える」ことでこれを解決してみましょう if ステートメントをすべて削除した何かが得られるまで、問題を言い換えます
言い換え 1: a > b の場合、a を返します。そうでない場合は b を返します
。 言い換え 2: (a - b) が負の場合は b を返します。
言い換え 3: (a - b) が負の場合、k = 1 とします。そうでなければ、k = 0 を返す a - k * (a - b)
を返す 言い換え 4: c = a - b を k = c の最上位ビットとする a - k * c を返す
int getMax(int a, int b) {
int c = a - b;
int k = (c >> ((sizeof(int) * CHAR_BIT) - 1)) & 0x1;
int max = a - k * c;
return max;
}
ソース: http://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/098478280X
編集:このコードは、ab がオーバーフローした場合でも機能します。ab >=0 の場合、k は 1、それ以外の場合は k=0 となるように、k を ab の符号と等しくします。q を k の逆数とします。上記のコードは、a が正または b が負、またはその逆の場合にオーバーフローします。a と b の符号が異なる場合、k を等号 (a) にする必要があります。
/* Flips 1 to 0 and vice-versa */
public static int flip(int bit){
return 1^bit;
}
/* returns 1 if a is positive, and 0 if a is negative */
public static int sign(int a){
return flip((a >> ((sizeof(int) * CHAR_BIT) - 1)) & 0x1);
}
public static int getMax(int a, int b){
int c = a - b;
int sa = sign(a-b); // if a>=0, then 1 else 0
int sb = sign(a-b); // if b>=1, then 1 else 0
int sc = sign(c); // depends on whether or not a-b overflows
/* If a and b have different signs, then k = sign(a) */
int use_sign_of_a = sa ^ sb;
/* If a and b have the same sign, then k = sign(a - b) */
int use_sign_of_c = flip(sa ^ sb);
int k = use_sign_of_a * sa + use_sign_of_c * sc;
int q = flip(k); //opposite of k
return a * k + b * q;
}