基本位运算
1、位基本操作符:
与 &
或 |
非
异或 ^
移位 >>、<<
2、应用:
1、判断一个数是不是4的次幂
( (x & (x - 1)) == 0 ) && ( (x & 0x55555555) == x)
2、获取负数
-x = (~x + 1)
3、交换两个数
int a, b;
a = a ^ b;
b = a ^ b;
a = a ^ b;
4、循环移位
(a << k) | ( a >> (32 - k) )
5:位运算实现加减乘除(ps:相对于硬件实现的+-*/效率低很多,放在此处仅仅练习位运算)
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> /* a + b */ int sum(int a, int b) { int t; while(b) { t = (a & b) << 1; a = a ^ b; b = t; } return a; } /* -a */ int neg(int a) { return sum(~a, 1); } /* a - b */ int sub(int a, int b) { return sum(a, neg(b)); } /* 判断a是不是负数 */ int ispos(int a) { if(a & (1 << 31) ) return 0; return 1; } /* a * b */ int mul(int a, int b) { int ans = 0; int flag = 0; if(!ispos(a)) { a = neg(a); flag ^= 1; } if(!ispos(b)) { b = neg(b); flag ^= 1; } while(b) { if(b & 1) ans = sum(ans, a); a = a << 1; b = b >> 1; } if(flag) ans = neg(ans); return ans; } /* a / b */ int Div(int a, int b) { int ans = 0; int flag = 0; if(!ispos(a)) { a = neg(a); flag ^= 1; } if(!ispos(b)) { b = neg(b); flag ^= 1; } int i; for(i = 31; i >= 0; i = sub(i, 1)) { if( (a >> i) >= b) { ans = sum(ans, 1 << i); a = sub(a, b << i); } } if(flag) ans = neg(ans); return ans; } int main() { struct timeval stime, etime; int a, b; long long i, j, u, v; i = j = u = v = 0; gettimeofday(&stime, NULL); for(a = -1000; a <= 1000; ++a) for(b = -1000; b <= 1000; ++b) { i += sum(a, b); j += sub(a, b); u += mul(a, b); if(b != 0) v += Div(a, b); } gettimeofday(&etime, NULL); printf("%ld\n", etime.tv_sec * 1000 + etime.tv_usec / 1000 - stime.tv_sec * 1000 - stime.tv_usec / 1000); return 0; }