本文共 1392 字,大约阅读时间需要 4 分钟。
有关位运算的一道题目
题目描述:
Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -。给出两个int数,不用+和-计算两个数的和并返回。
意思大概是在比特位上作一个模拟的进制运算,1和1进位1,1和0或0和1(再加上前面是否有进位而来的1)判断是否进位,一直到末尾。
位运算的基本知识:
&:与号,两个位都为1时,结果才为1| :或号,两个位都为0时,结果才为0^ :异或,两个位相同为0,相异为1~ :取反,0变1,1变0(所有的位)<<:左移,全部位向左边移动若干位,高位丢弃,低位补0>>:右移,各二进制位全部右移若干位,对无符号,高位补0,有符号数,各编译器处理的方法不一样: 有的补符号位(算术右移,就是符号位一直都不变,正负都一样,后面的值你自己去移去) 有的补0(逻辑右移,变成了正数了)
这里我们用到的是^和&
int getSum(int a, int b) { while(a != 0){ int temp = (a&b)<<1; //找到所有要进位的位,temp == 0说明已经没有要进位的位了 b = a ^ b; //得到新的b,与上一步得到的已经进了1的位异或 a = temp; //更新a,保存下一次需要进位的位,如果为0,说明没有需要进位的了 } return b; }
稍微走一遍:
1.首先计算需要进位的全部位(a&b),假设a =1 = 0001,b = 3 = 0011,那么a&b = 0001,也就是说第一位需要进位,这时候<<1,左移1位,下一个循环参加运算的a就成了0010,a = 0010 2.b = a ^ b,将a中无关进位的位正常加起来,b = 0001 ^ 0011 = 0010 3.a换成之前保存的需要进位的temp,a == temp == 0010 != 0,那就说明还有需要前进的位。a == 0010 != 0,下一次循环: temp = (a&b)<<1 = 0100 b = 0000 a = 0100a == 0100 != 0,继续循环: temp = 0000 b = 0100 a = 0000结束循环
总结一下:
以b为result,a & b标识着a和b中需要进的位,也就是 1 1 , temp呢?就直接把这种位全部左移一位,相当于标识了下次需要考虑的位 a ^ b,对应位如果是0 1 ; 1 0只需要在新的值的对应位上置一个1 , 1 1就需要进位了(这里就标识为一个0,其实相当于进位了,因为上面得到的temp下次循环和b进行了异或^,如果依然是1 1,继续标识0,进位,直到异或得到1,说明不用再进位了)转载地址:http://kemmi.baihongyu.com/