[CareerCup] 17.4 Maximum of Two Numbers 兩數中的較大值
阿新 • • 發佈:2018-12-27
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; }