位运算集锦

文中2'k代表2的k次方

 

1 除以2的k次幂可以用位运算:

n/2'k == n>>k

 

2 对2的k次幂取余数可以用位运算:

n%2'k == n & ((1<<k)-1)

比如 100%32

100的二进制为          1100100

((1<<5)-1)等于31为  0011111

两个数相与即得 100,故

100%32 = 4

 

3 对于整数n,从低位开始,把它的第k位(0<=k<=31)置为1的操作为:

n = n | (1<<k)

 

4 对于整数n,从低位开始,把它的第k位(0<=k<=31)置为0的操作为:

n = n & ~(1<<k)

 

 

5 对于整数n,从低位开始,测试它的第k位(0<=k<=31)是否为1,若为1,返回一个大于0的数,否则返回0

return  n & (1<<k)

 

6 对于整数n,判断它是奇数还是偶数

n & 1大于0,则n是奇数,否则n是偶数

 

7 对于整数n,若n是奇数,则把n减1变成偶数,若n是偶数,则把n加1变成奇数

n = n ^ 1

 

8 对于奇数n,有如下性质

(n-1) ^ n ==1

 

9 最大的int

01 1111111111 1111111111 1111111111

MAX_INT = ~(1<<31)

 

10 最小的int

10 0000000000 0000000000 0000000000

MIN_INT = (1<<31)

 

11 把最低位的1变为0

比如: 111000   ---> 110000

n = n - (n&-n)

 

12 判断两个整数数是否同号

#define MASK 0x80000000

flag = (x & MASK) ^ (y & MASK)

如果flag为0,说明不同号,否则同号

 

13 交换两个值,不用临时变量

想将a和b的值互换,可以用以下赋值语句实现:
    a=a∧b;
    b=b∧a;
    a=a∧b;

 

 

14 bitset的C语言实现

 

#include <stdio.h>
#include <string.h>

#define N 4000000000
#define SHIFT 5
#define MASK 0x1f

int a[1+N/32];

void set(unsigned int i) 
{
	a[i>>SHIFT] |= (1 << (i & MASK));		// a[i/32] |= (1 << i%32)
}

void clr(unsigned int i)
{
	a[i>>SHIFT] &= ~(1 << (i & MASK));   // a[i/32] &=  ~(1 << i%32)
}

unsigned int test(unsigned int i)
{
	return a[i>>SHIFT] & (1 << (i & MASK));    // a[i/32] & (1 << i%32)
}

int main()
{
	unsigned int		i;

	memset(a, 0, sizeof(a));

	for (i = 0; i < N; i++) {
		set(i);
	}
	for (i = 0; i < 10; i++) {
		if(test(i)) {
			printf("%d exitst\n", i);
		}
	}
	getchar();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值