//只能用于整型数据,float,double不可以
/* bit_get */
int bit_get(constunsigned char *bits,int pos)
{
unsigned char mask;
int i;
/* Set a mask for the bit to get. */
mask = 0x80;
for(i = 0; i< (pos % 8); i++)
mask = mask >> 1;
/* Get the bit. */
return(((mask & bits[(int)(pos/ 8)]) == mask) ? 1 : 0);
}
**********************************************************************************
追加:
比如随机数:
time_t ti; srand((unsignedint)time(&ti));
int num=rand()%10; //表示的就是num取值范围是0-9
同理
int loc=pos%8的取值范围就是0-7,也就是char是一个字节,loc表示的是其中0-7上的某一位
而bits[pos/8]是针对于实参为bits=(char*)(&int)这种类型,同时pos=10,也就是说针对第二个字节bits[1]
和mask进行运算
组和个的问题:
如果以“个”为索引index,则index/8则表示8个一组,index处于第几组里面
index%8则表示index在一组(这个组并不一定是第一个组,是index/8组)当中的第几个
***********************************************************************************
/* bit_set */
void bit_set(unsigned char *bits, int pos, int state)
{
unsigned char mask;
int i;
/* Set a mask for the bit to set. */
mask = 0x80;
for(1= 0; i < (pos % 8); i++)
mask = mask >> 1;
/* Set the bit. */
if(state)
bits[pos / 8]= bits[pos/ 8] | mask;
else
bits[pos / 8]= bits[pos/ B]& (~mask);
return;
}
https://my.oschina.net/u/249511/blog/48928
用一般的
(a >= 0) && (a <= 65535)
可能要两次判断。65535就是0xffff 1111 1111 1111 1111 16位,2个字节
0000 0000 0000 0001 (1<<16) 1000 0000 0000 0000 1 0000 0000 0000 0000 ((1<<16)-1) 1111 1111 1111 1111
65538 1 0000 0000 0000 0010 (~(1<<16)-1)
-4 0000 0100 ->1111 1011 -> 1111 1100
改用位运算只要一次:a & ~((1 << 16)-1)
一个整数a, a & 1 这个表达式可以用来判断a的奇偶性。二进制的末位为表示偶数,最末位为1表示奇数。使用a%2来判断奇偶性和a & 1是一样的作用,但是a & 1要快好多。
判断n是否是2的正整数冪:(!(n&(n-1)) ) && n
例:如果n = 16 = 10000, n-1 = 1111 从理论上讲,如果一个数a他是2的正整数幂,那么a 的二进制形式必定为1000…..(后面有个或者多个)
常用的二进制数:
0xAAAAAAAA= 1010 1010 1010 1010 1010 1010 1010 1010
0x55555555 = 101 0101 0101 0101 0101 0101 0101 0 1 0 1(奇数位为1,以1位为单位提取奇偶位)
0xCCCCCCCC = 110011001100 1100 1100 1100 1100 1100
0x33333333 = 11 0011 0011 0011 0011 0011 00 11 00 11(以“2位”为单位提取奇偶位)
0xF0F0F0F0 = 11110000111100001111000011110000
0x0F0F0F0F = 1111 00001111 00001111 00001111(以“8位”为单位提取奇偶位)
0xFFFF0000 =11111111111111110000000000000000
0x0000FFFF = 1111111111111111(以“16位”为单位提取奇偶位)
0xAAAAAAAA 10101010101010101010101010101010
0x55555555 01010101010101010101010101010101
0xCCCCCCCC 11001100110011001100110011001100
0x33333333 00110011001100110011001100110011
0xF0F0F0F0 11110000111100001111000011110000
0x0F0F0F0F 00001111000011110000111100001111
0xFF00FF00 11111111000000001111111100000000
0x00FF00FF 00000000111111110000000011111111
0xFFFF0000 11111111111111110000000000000000
0x0000FFFF 00000000000000001111111111111111
32位无符号数的1的个数可以这样数:
int count_one(unsigned long n)
{
// 0xAAAAAAAA,0x55555555分别是以“1位”为单位提取奇偶位
n = ((n & 0xAAAAAAAA ) >> 1 ) + (n & 0x55555555 );
// 0xCCCCCCCC,0x33333333分别是以“2位”为单位提取奇偶位
n = ((n & 0xCCCCCCCC ) >> 2 ) + (n & 0x33333333 );
// 0xF0F0F0F0,0x0F0F0F0F分别是以“4位”为单位提取奇偶位
n = ((n & 0xF0F0F0F0 ) >> 4 ) + (n & 0x0F0F0F0F );
// 0xFF00FF00,0x00FF00FF分别是以“8位”为单位提取奇偶位
n = ((n & 0xFF00FF00 ) >> 8 ) + (n & 0x00FF00FF );
// 0xFFFF0000,0x0000FFFF分别是以“16位”为单位提取奇偶位
n = ((n & 0xFFFF0000 ) >> 16 ) + (n & 0x0000FFFF );
return n;
}
对于正整数的模运算(注意,负数不能这么算)
乘除法是很消耗时间的,只要对数左移一位就是乘以2,右移一位就是除以2,传说用位运算效率提高了60%。
乘2^k 众所周知: n<<k 除2^k众所周知: n>>k。
对2的倍数取模:n&((1<<k)-1)
计算掩码:
截取低6位的掩码:0×3F
用位运算这么表示:(1 << 6) - 1
整数交换:
a = a ^ b;b = a ^ b;a = a ^ b;
判断奇偶:a&1==0就是偶数,否则是奇数
因为奇数二进制末位总为1,偶数总为0
http://blog.tomtung.com/2007/05/bitwise-operation/
for(int i=1;i<=7;i++)
cout<<i+1>>1<<endl;
1 2 3 4 5 6 7 8 9 ....n....
1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 ........
>>1表示除以2也就是2个一组
cout<<i>>1<<endl;
1 2 3 4 5 6 7 8 9 ....n....
0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 ........
改变符号:如n->-n ~n+1
这个表达式用于字节对齐方面:
int size;
size+=size&1;
解析:
size取值可以为:0,1,2,3,4,5,6,7,8
经过size=size+(size&1)之后
size的值为:0,2,2,4,4,6,6,8,8
表示以2对齐,所以不足2的都用2表示
template<class T>
vector<T>::resize(int newsize)
{
int size=d_size; //这个size是4字节对齐,size=1表示vector中有一个元素,占4字节,如果这个元素为8字节
//则size=2,用两个4字节存储
newsize*=sizeof(T)>>2;
int32 *new_storage=(int32)malloc(newsize);
memset(new_storage,0,(newsize+(newsize&1))<<2);
}