位操作

来源:互联网 发布:java基础代码 编辑:程序博客网 时间:2024/05/16 12:06

//只能用于整型数据,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的正整数幂,那么的二进制形式必定为1000…..(后面有个或者多个

常用的二进制数:
0xAAAAAAAA= 1010 1010 1010 1010 1010 1010 1010 1010
0x55555555 = 101 0101 0101 0101 0101 0101 0101 0 1 0 1(奇数位为11位为单位提取奇偶位
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);
}













原创粉丝点击