编程小技巧

代码中常用的宏:

#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。


你可能感兴趣的:(编程小技巧)