1. 程式人生 > >【筆試題分享】異或與位運算的巧用

【筆試題分享】異或與位運算的巧用

第1題 

假設xy都是整數,如果得到其中較小的那個。

微軟2012暑期實習生筆試題。這是道選擇題,從給出的四個選項中選出一個正確的答案。

仔細想想之後,發現A是正確解:y^( (x^y)& -(x<y) ) 

(現在才認識到異或的神奇之處)

說明自己的理解:

1. 對於(x<y)的判定部分, 如果x<y為真,判斷結果為1, 那麼-(x<y)就得-1(補碼錶示為全1,只考慮8int型,則為 11111111);  如果x<y為假,判斷結果為0(補碼錶示為 00000000

2. 對於(x^y),當(x<y)為真時,(x^y)&(11111111) = (x^y); 

(x<y)為假時,(x^y)&(00000000)0

3. 最後,y^(x^y) = x , 前提是x<y為真;y^0 = y, 前提是x<y為假。

成立。

第2題 

最近做的一道筆試題

寫一個巨集定義,實現的功能是將一個int型的數的奇偶位互換,例如62進製為0110, 第一位與第二位互換,第三位與第四位互換,得到1001,輸出應該為.

完整的程式碼為

#include<iostream>
#include<string>
using namespace std;
#define N(n) ((n<<1)&(0xAAAA))|((n>>1)&(0x5555))  // 此句為解


void main(){
    int k=N(6);
    cout<<k<<endl;
}

自己的理解:

為簡化說明,以4位二進位制碼為例。

1. 0xAAAA 的二進位制類似於 10100x5555 的二進位制類似於 0101

2. (n<<1)&(0xAAAA)

n先左移1位,再與1010做與運算,只保留移位之後的偶數位的值,奇數位全為0,實際上是隻保留了n的奇數位的值,並把它們交換到了偶數位上。比如 n = 0110 , n<<1 = 1100, (n<<1) & 1010 = 1000 ;

3. (n>>1)&(0x5555)

n右移一位,再與0101 做與運算,只保留移位之後的奇數位的值,偶數位全為0,實際是隻保留的偶數位的值,並把它們交換到對應的奇數位上。n = 0110, n>>1 = 0011, (n>>1) & 0101 = 0001;

4. 最後做或運算, 得1001

第3題

還有一個關於異或運算的。

如何將a,b的值交換,而不用第三個變數

異或的作用:

a=a^b;

b=a^b;

a=a^b;

即可。