代码中常用的宏:
#define MIN(a, b)(((a)<(b))?(a):(b))
#define MAX(a, b)(((a)>(b))?(a):(b))
#define ROUNDUP(x,y) ((((ulong)(x)+((y)-1))/(y))*(y))
#define ISALIGNED(a,x) (((uint)(a) &((x)-1)) == 0)
#define ISPOWEROF2(x) ((((x)-1)&(x))==0)
#define OFFSETOF(type,member) ((uint) &((type*)0)->member)
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
#define XXD(x, n) ((x) & ((n) - 1)) /*取模,n必须是2的幂,此方法比%快*/
#define LIGN(a,n) ((a + (n - 1)) & ~(n - 1)) /*同ROUNDUP,n必须是2的幂*/
字节序转换
方法一:
unsigned int _shr_swap32(unsigned int i)
{
i = (i << 16) | (i >> 16);
return (i & 0xff00ffff) >> 8 | (i & 0xffff00ff) << 8;
}
unsigned short _shr_swap16(unsigned short i)
{
return i << 8 | i >> 8;
}
方法二:
/* Byte swap a 16 bit value */
#define SWAP16(val) \
((uint16)( \
(((uint16)(val) & (uint16)0x00ffU) << 8) | \
(((uint16)(val) & (uint16)0xff00U) >> 8) ))
/* Byte swap a 32 bit value */
#define SWAP32(val) \
((uint32)( \
(((uint32)(val) & (uint32)0x000000ffUL) << 24) | \
(((uint32)(val) & (uint32)0x0000ff00UL) << 8) | \
(((uint32)(val) & (uint32)0x00ff0000UL) >> 8) | \
(((uint32)(val) & (uint32)0xff000000UL) >> 24) ))
计算bit位置1的个数
int bit_count(unsigned int n)
{
n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f);
n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff);
n = (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff);
return n;
}
没有循环,5个位运算语句,一次搞定。
比如这个例子,143的二进制表示是10001111,这里只有8位,高位的0怎么进行与的位运算也是0,所以只考虑低位的运算,按照这个算法走一次
+---+---+---+---+---+---+---+---+
| 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | <---143
+---+---+---+---+---+---+---+---+
| 0 1 | 0 0 | 1 0 | 1 0 | <---第一次运算后
+-------+-------+-------+-------+
| 0 0 0 1 | 0 1 0 0 | <---第二次运算后
+---------------+---------------+
| 0 0 0 0 0 1 0 1 | <---第三次运算后,得数为5
+-------------------------------+
这里运用了分治的思想,先计算每对相邻的2位中有几个1,再计算每相邻的4位中有几个1,下来8位,16位,32位,因为2^5=32,所以对于32位的机器,5条位运算语句就够了。
像这里第二行第一个格子中,01就表示前两位有1个1,00表示下来的两位中没有1,其实同理。再下来01+00=0001表示前四位中有1个1,同样的10+10=0100表示低四位中有4个1,最后一步0001+0100=00000101表示整个8位中有5个1。