《剑指Offer》P238,《程序员面试宝典》P40
分析:没有进位的加法运算可以用异或^来实现
进位只有1&1存在进位问题,故先做位与&,再往前进一位,即左移一位
不断循环和递归,直至进位为0,不产生进位,最终实现加法运算
方法一:递归实现
int Add(int num1,int num2) { if(num2 == 0) { return; } int sum ,carry; sum = num1 ^ num2; carry = (num1 & num2) << 1; return Add(sum,carry); }
方法二:循环实现
int Add(int num1,int num2) { int sum ,carry; do { sum = num1 ^ num2; carry = (num1 & num2) << 1; num1 = sum; num2 = carry; } while(num2 != 0) return num1; }
Tips1:判断一个数是否是2^N,不用循环语句进行判断;
分析:由2^N二进制写成100000…的形式,故X&(X-1)=0;
结果:!(X&(X-1))为真
发散:1).用以解决求取数字中1的个数的问题
leetcode-191Number of 1 Bits二进制数字中1的个数
http://blog.csdn.net/woliuyunyicai/article/details/44179743
2).求出一个数最合适(大于该数)的2^N
Java中ArrayQueue实现方法:
if (numElements >= initialCapacity) { initialCapacity = numElements; initialCapacity |= (initialCapacity >>> 1); initialCapacity |= (initialCapacity >>> 2); initialCapacity |= (initialCapacity >>> 4); initialCapacity |= (initialCapacity >>> 8); initialCapacity |= (initialCapacity >>> 16); initialCapacity++; if (initialCapacity < 0) // 对应(0x7FFFFFF++)的情况 initialCapacity >>>= 1;// 则右移一位,分配2^30块内存 }
Tips 2.(x&y)+((x^y)>>1) = (x+y)/2
解析:x&y为x,y相同位上的值(0或1)相加乘以1/2(如1&1 = 1,(1+1)/2=1);不同位置0;
x^y 同理指在不同位上的值相加的结果,相同位置0(1^0 = 1;(1+0)=1)
Tips 3.不用判断语句找出两个数字a,b之间的较大值
方法一:int max = ((a+b)+ abs(a-b))/2 //利用数学方法 方法二:int num[2] = {a,b}; int c = a- b; c = unsigned(c) >> (sizeof(int)*8 -1); int max = num[c];
解析:即若a>b,则c>0,符号位=0;否则,符号位=1;右移31位获得符号位