1. 程式人生 > >[CareerCup] 17.4 Maximum of Two Numbers 兩數中的較大值

[CareerCup] 17.4 Maximum of Two Numbers 兩數中的較大值

17.4 Write a method which finds the maximum of two numbers. You should not use if-else or any other comparison operator.

這道題讓我們找出兩個數中的較大值,不能用if..else..語句判斷,也不能用任何比較符號。那麼我們怎麼辦呢,我們看兩個數的差值a-b是否大於0,如果大於0,說明a大,如果小於0,說明b大。然後我們用一個變數k來記錄a-b的符號位,用q來表示k的相反數,這樣當a大的時候,k=1, q=0,反之當b大的時候,k=0,q=1,那麼我們只要用a*k + b*q就能得到較大數了:

int flip(int bit) {
    return 1 ^ bit;
}

int sign(int a) {
    return flip((a >> 31) & 0x1);
}

int getMaxNaive(int a, int b) {
    int k = sign(a - b);
    int q = flip(k);
    return a * k + b * q;
}

但是上面的解法有時候會有問題,比如當a=INT_MAX-2, b = -15的時候,a-b就會溢位,那麼我們怎麼辦呢?溢位的情況只會發生在當a是正數,而b是負數的時候,或者反回來的情況,也就是說a和b符號不同。那麼我們讓k = sign(a),邏輯如下:

當a和b的符號不同,k = sign(a)

否則,k = sign(a - b)

那麼我們可以分別儲存a,b和a-b的符號,然後我們判斷a和b的符號是否相同,如果不相同我們用a的符號,如果相同,我們用a-b的符號,這樣我們就可以避免溢位得到正確的k,之後就跟上面的方法完全一樣了:

int getMax(int a, int b) {
    int c = a - b;
    int sa = sign(a), sb = sign(b), sc = sign(c);
    int m = sa ^ sb, n = flip(sa ^ sb);
    int k = m * sa + n * sc, q = flip(k);
    
return a * k + b * q; }