第1题
假设x和y都是整数,如果得到其中较小的那个。
微软2012暑期实习生笔试题。这是道选择题,从给出的四个选项中选出一个正确的答案。
仔细想想之后,发现A是正确解:y^( (x^y)& -(x<y) )
(现在才认识到异或的神奇之处)
说明自己的理解:
1. 对于(x<y)的判定部分, 如果x<y为真,判断结果为1, 那么-(x<y)就得-1(补码表示为全1,只考虑8位int型,则为 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型的数的奇偶位互换,例如6的2进制为0110, 第一位与第二位互换,第三位与第四位互换,得到1001,输出应该为9 .
完整的代码为
#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 的二进制类似于 1010;0x5555 的二进制类似于 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 的偶数位的值,并把它们交换到对应的奇数位上。n = 0110, n>>1 = 0011, (n>>1) & 0101 = 0001;
4. 最后做或运算, 得1001。
第3题
还有一个关于异或运算的。
如何将a,b的值交换,而不用第三个变量
异或的作用:
a=a^b;
b=a^b;
a=a^b;
即可。