3、高性能函数


关闭最靠右的位元(0101 1110=>0101 1100),可判断无符号整数是不是2的幂或0,即结果是否为0;

// 关闭最靠右的位元(0101 1110=>0101 1100),可判断无符号整数是不是2的幂或0,即结果是否为0;
#define TurnOffLastRightBit(x)          ((x) & ((x)-1))

打开最靠右的位元(0101 0111=>0101 1111);

// 打开最靠右的位元(0101 0111=>0101 1111);
#define TurnOnLastRightBit(x)           ((x) | ((x)+1))

关闭字组尾部的1(0101 0111=>0101 0000),可判断无符号整数是不是2^n-1或0,也可判断某个数的所有位元是否均为1,即结果是否为0;

// 关闭字组尾部的1(0101 0111=>0101 0000),可判断无符号整数是不是2^n-1或0,也可判断某个数的所有位元是否均为1,即结果是否为0;
#define TurnOffTailBit(x)               ((x) & ((x)+1))

打开字组尾部的0(0101 1000=>0101 1111);

// 打开字组尾部的0(0101 1000=>0101 1111);
#define TurnOnTailBit(x)                ((x) | ((x)-1))

 转换x最靠右且值为0的位于变为1,其余位元置0(1010 0111=>0000 1000),若x中没有0的位元,则结果为0;

// 转换x最靠右且值为0的位于变为1,其余位元置0(1010 0111=>0000 1000),若x中没有0的位元,则结果为0;
#define TrunLastRightBit0(x)            (~(x) & ((x)+1))

转换x最靠右且为1的位元变为0,其余位元置1(1010 1000=>1111 0111),若x中没有1的位元,则结果的每个位元均是1;

// 转换x最靠右且为1的位元变为0,其余位元置1(1010 1000=>1111 0111),若x中没有1的位元,则结果的每个位元均是1;
#define TrunLastRightBit1(x)            (~(x) | ((x)-1))

转换x尾部所有为0的位元变为1,其余位元置0(1010 0111=>1111 1000),若x没有0的位元,则结果为0;

// 转换x尾部所有为0的位元变为1,其余位元置0(1010 0111=>1111 1000),若x没有0的位元,则结果为0;
#define TrunTailBit0(x)                 (~(x) & ((x)-1))

转换x尾部所有为1的位元变为0,其余位元置1(1010 0111=>1111 1000),若x没有1的位元,则结果的每个位元均是1;

// 转换x尾部所有为1的位元变为0,其余位元置1(1010 0111=>1111 1000),若x没有1的位元,则结果的每个位元均是1;
#define TrunTailBit1(x)                 (~(x) | ((x)+1))

获取x最靠右且为1的位元,其余位元置0(0101 1000=>0000 1000),若x没有1的位元,则结果为0;

// 获取x最靠右且为1的位元,其余位元置0(0101 1000=>0000 1000),若x没有1的位元,则结果为0;
#define GetLastRightBit1(x)             ((x) & (~(x)+1))

获取x最靠右且为0的位元,其余位元置1(0101 0111=>1111 0111),若x没有0的位元,则结果为1;

// 获取x最靠右且为0的位元,其余位元置1(0101 0111=>1111 0111),若x没有0的位元,则结果为1;
#define GetLastRightBit0(x)             ((x) | (~(x)-1))

获取x最靠右且为1的位元及其右侧均置1,其左侧均置0(0101 1000=>0000 1111),若x没有1的位元,则结果的每个位元均是1;

// 获取x最靠右且为1的位元及其右侧均置1,其左侧均置0(0101 1000=>0000 1111),若x没有1的位元,则结果的每个位元均是1;
#define GetTailBit1(x)                  ((x) ^ ((x)-1))

获取x最靠右且为0的位元及其右侧均置1,其左侧均置0(0101 0111=>0000 1111),若x没有0的位元,则结果的每个位元均是1;

// 获取x最靠右且为0的位元及其右侧均置1,其左侧均置0(0101 0111=>0000 1111),若x没有0的位元,则结果的每个位元均是1;
#define GetTailBit0(x)                  ((x) ^ ((x)+1))

设置x右侧连续出现且为1的位元置0(0101 1100=>0100 0000); /* ((((x) & -(x)) + (x)) & (x)) */

// 设置x右侧连续出现且为1的位元置0(0101 1100=>0100 0000); /* ((((x) & -(x)) + (x)) & (x)) */
#define TurnOffRightContinueBit(x)      ((((x) | ((x)-1)) + 1) & (x))

交换不同寄存器中相应的位段;

// 交换不同寄存器中相应的位段;
#define SwapBitField(x, y, mask)        {(x) = (x) ^ (y); (y) = (y) ^ ((x) & (mask)); (x) = (x) ^ (y);}

绝对值函数;

//绝对值函数;
#define ABS(x)                          (((x) ^ ((signed)(x) >> 31)) - ((signed)(x) >> 31))
#define NABS(x)                         (((signed)(x) >> 31) - ((x) ^ ((signed)(x) >> 31)))

平均值函数;

// 平均值函数;
#define AVEF(x, y)                      (((x) & (y)) + ((unsigned)((x) ^ (y)) >> 1))
#define AVEC(x, y)                      (((x) | (y)) - (((x) ^ (y)) >> 1))

符号函数;

// 符号函数;
#define SIGN(x)                         (((x) >> 31) | ((unsigned)(-(x)) >> 31))

比较函数;

// 比较函数;
#define CMP(x, y)                       (((x) > (y)) - ((x) < (y)))

二进制转格雷码;

// 二进制转格雷码;
#define B2G(b, g)                       (g) = ((b) ^ ((unsigned)(b) >> 1))
#define G2B(g, b)   \
{   \
    (b) = (g) ^ ((unsigned)(g) >> 1);   \
    (b) = (b) ^ ((unsigned)(b) >> 2);   \
    (b) = (b) ^ ((unsigned)(b) >> 4);   \
    if(sizeof(g) > 1) (b) = (b) ^ ((unsigned)(b) >> 8);   \
    if(sizeof(g) > 2) (b) = (b) ^ ((unsigned)(b) >> 16);   \
}

三角函数;

#define PI              3.14159265358979323846
#define SIN(x)          sin((x) * PI / 180)
#define COS(x)          cos((x) * PI / 180)
#define TAN(x)          tan((x) * PI / 180)
#define ASIN(x)         (asin(x) / PI * 180)
#define ACOS(x)         (acos(x) / PI * 180)
#define ATAN(x)         (atan(x) / PI * 180)

最大公约数;

template<typename T>
T GCD(T a, T b)
{
    while(b ^= a ^= b ^= a %= b);
    return a;
}

最小公倍数;

// 最小公倍数;
template<typename T>
T LCM(T a, int b)
{
    return a * b / GCD(a, b);
}

统计值为1的位元数;

int PopCount(unsigned int x)
{
#if 0
    int count = 0;

    for (; x; count ++) {
        x &= x - 1;
    }

    return count;
#endif
#if 0
    x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
    x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f);
    x = (x & 0x00ff00ff) + ((x >> 8) & 0x00ff00ff);
    x = (x & 0x0000ffff) + ((x >> 16) & 0x0000ffff);

    return x;
#endif
#if 0
    static const int ones[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2,\
     3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4,\
     3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2,\
     3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5,\
     5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5,\
     6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,\
     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3,\
     4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3,\
     3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5,\
     6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6,\
     5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};

    return (ones[x & 0xff] + ones[(x >> 8) & 0xff] + ones[(x >> 16) & 0xff] + ones[(x >> 24) & 0xff]);
#endif
#if 0
    x = x - ((x >> 1) & 0x55555555);
    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
    x = (x + (x >> 4)) & 0x0f0f0f0f;
    x = x + (x >> 8);
    x = x + (x >> 16);
    return x & 0x0000003f;
#endif
#if 0
    unsigned int n;
    n = (x >> 1) & 033333333333;    // Count bits in;
    x = x - n;                      // each 3-bit;
    n = (n >> 1) & 033333333333;    // field;
    x = x - n;
    x = (x + (x >> 3)) & 030707070707;  // 6-bit sums;
    return x % 63;                  // Add 6-bit sums;
#endif
#if 1
    unsigned int n;
    n = (x >> 1) & 0x77777777;      // Count bits in;
    x = x - n;                      // each 4-bit;
    n = (n >> 1) & 0x77777777;      // field;
    x = x - n;
    n = (n >> 1) & 0x77777777;
    x = x - n;
    x = (x + (x >> 4)) & 0x0f0f0f0f;    // Get byte sums;
    x = x*0x01010101;                   // Add the bytes;
    return x >> 24;
#endif
}

Hamming Distance;

// Hamming Distance;
#define HammDist(x, y)      PopCount(x ^ y)

计算两个字组种群计数之差,pop(x) - pop(y);

// 计算两个字组种群计数之差,pop(x) - pop(y);
int PopDiff(unsigned int x, unsigned int y)
{
    x = x - ((x >> 1) & 0x55555555);
    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
    y = ~y;
    y = y - ((y >> 1) & 0x55555555);
    y = (y & 0x33333333) + ((y >> 2) & 0x33333333);
    x = x + y;
    x = x + (x >> 8);
    x = x + (x >> 16);
    return (x & 0x0000007f) - 32;
}

比较pop(x)与pop(y)的大小;

// 比较pop(x)与pop(y)的大小;
int PopCmpr(unsigned int xp, unsigned int yp)
{
    unsigned int x, y;
    x = xp & ~yp;           // Clear bits where;
    y = yp & ~xp;
    while (1) {
        if(x == 0) return y | -(int)y;
        if(y == 0) return 1;
        x = x & (x - 1);    // Clear one bit;
        y = y & (y - 1);
    }
}

进位保留加法器(carry-save adder, CSA);

// 进位保留加法器(carry-save adder, CSA);
#define CSA(h, l, a, b, c)  \
{   \
    unsigned int u = a ^ b; \
    unsigned int v = c;     \
    h = (a & b) | (u & v);  \
    l = u ^ v;              \
}

求数组中的种群计数,每次处理两个字组元素;


// 求数组中的种群计数,每次处理两个字组元素;
int PopArray(unsigned int A[], int n)
{
#if 0
    int tot, i;
    unsigned int ones, twos;

    tot = 0;
    ones = 0;
    for(i=0; i<=n-2; i+=2){
        CSA(twos, ones, ones, A[i], A[i+1]);
        tot = tot + PopCount(twos);
    }
    tot = 2 * tot + PopCount(ones);

    // If there's a last one, add it in;
    if(n & 1) tot = tot + PopCount(A[i]);

    return tot;
#else
    int tot, i;
    unsigned int ones, twos, twosA, twosB,
            fours, foursA, foursB, eights;

    tot = 0;
    fours = twos = ones = 0;

    for(i=0; i<=n-8; i+=8){
        CSA(twosA, ones, ones, A[i], A[i+1]);
        CSA(twosB, ones, ones, A[i+2], A[i+3]);
        CSA(foursA, twos, twos, twosA, twosB);
        CSA(twosA, ones, ones, A[i+4], A[i+5]);
        CSA(twosB, ones, ones, A[i+6], A[i+7]);
        CSA(foursB, twos, twos, twosA, twosB);
        CSA(eights, fours, fours, foursA, foursB);
        tot += PopCount(eights);
    }
    tot = 8*tot + 4*PopCount(fours) + 2*PopCount(twos) + PopCount(ones);

    // Simly ad in the last 0 to 7 elements;
    for(i=i; i<n; i++) tot += PopCount(A[i]);

    return tot;
#endif
}

判断字组中值为‘1’的位元个数是奇数还是偶数;


// 判断字组中值为‘1’的位元个数是奇数还是偶数;
int ParityCheck(unsigned int x)
{
#if 1
    unsigned int y;
    y = x ^ (x >> 1);
    y = y ^ (y >> 2);
    y = y ^ (y >> 4);
    y = y ^ (y >> 8);
    y = y ^ (y >> 16);
    return y;
#else
    x = x ^ (x >> 1);
    x = (x ^ (x >> 2)) & 0x11111111;
    x = x * 0x11111111;
    return (x >> 28) & 1;
#endif
}

计算x前导0的个数(大端);

// 计算x前导0的个数(大端);
unsigned int Nlz(unsigned int x)
{
 #if 0
    int n;

    if(x == 0) return 32;
    n = 1;
    if((x >> 16) == 0){n += 16; x <<= 16;}
    if((x >> 24) == 0){n += 8; x <<= 8;}
    if((x >> 28) == 0){n += 4; x <<= 4;}
    if((x >> 30) == 0){n += 2; x <<= 2;}
    n -= (x >> 31);
    return n;
#endif
#if 0
    unsigned int y;
    int n = 32;

    y = x >> 16; if(y != 0){n -= 16; x = y;}
    y = x >> 8; if(y != 0){n -= 8; x = y;}
    y = x >> 4; if(y != 0){n -= 4; x = y;}
    y = x >> 2; if(y != 0){n -= 2; x = y;}
    y = x >> 1; if(y != 0) return n - 2;

    return n - x;
#endif
#if 0
    static char table[256] = {
        0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
    };
    return 32 - table[x & 0xff] - table[(x >> 8) & 0xff] - table[(x >> 16) & 0xff] - table[(x >> 24) & 0xff];
#endif
#if 0
    int y, n;
    n = 0;
    y = x;
    while(1){
        if(x < 0) return n;
        if(y == 0) return 32 - n;
        n++;
        x <<= 1;
        y >>= 1;
    }
#endif
#if 0
    int y, m, n;
    y = -(x >> 16);         // If left half of x is 0,
    m = (y >> 16) & 16;     // set n = 16. If left half
    n = 16 - m;             // is nonzero, set n = 0 and
    x = x >> m;             // shift x right 16.
                            // Now x is of the from 0000xxxx.
    y = x - 0x100;          // If positions 8-15 are 0,
    m = (y >> 16) & 8;      // add 8 to n and shift x left 8.
    n = n + m;
    x = x << m;

    y = x - 0x1000;         // If positions 12-15 are 0,
    m = (y >> 16) & 4;      // add 4 to n and shift x left 4.
    n = n + m;
    x = x << m;

    y = x - 0x4000;         // If positions 14-15 are 0,
    m = (y >> 16) & 2;      // add 2 to n and shift x left 2.
    n = n + m;
    x = x << m;

    y = x >> 14;            // Set y = 0, 1, 2, or 3.
    m = y & ~(y >> 1);      // Set m = 0, 1, 2, or w resp.
    return n + 2 - m;
#endif
#if 1
#define u   ' '
    static char table[64] = {
        32, 31, u, 16, u, 30, 3, u,     15, u, u, u, 29, 10, 2, u,
        u, u, 12, 14, 21, u, 19, u,     u, 28, u, 25, u, 9, 1, u,
        17, u, 4, u, u, u, 11, u,       13, 22, 20, u, 26, u, u, 18,
        5, u, u, 23, u, 27, u, 6,       u, 24, 7, u, 8, u, 0, u
    };
#undef  u
    x = x | (x >> 1);       // Propagate leftmost
    x = x | (x >> 2);       // 1-bit to the right.
    x = x | (x >> 4);
    x = x | (x >> 8);
    x = x | (x >> 16);
    x = x * 0x06eb14f9;     // Multiplier is 7*255**3.
    return table[x >> 26];
#endif
}

计算x尾部0的个数(小端);

// 计算x尾部0的个数(小端);
unsigned int Ntz(unsigned int x)
{
#if 0
   int n;

   if(x == 0) return 32;
   n = 1;
   if((x & 0x0000ffff) == 0){n += 16; x >>= 16;}
   if((x & 0x000000ff) == 0){n += 8; x >>= 8;}
   if((x & 0x0000000f) == 0){n += 4; x >>= 4;}
   if((x & 0x00000003) == 0){n += 2; x >>= 2;}
   return n - (x & 1);
#endif
#if 0
   unsigned y, bz, b4, b3, b2, b1, b0;

   y = x & -x;              // Isolate rightmost 1-bit;
   bz = y ? 0 : 1;          // 1 if y = 0;
   b4 = (y & 0x0000ffff) ? 0 : 16;
   b3 = (y & 0x00ff00ff) ? 0 : 8;
   b2 = (y & 0x0f0f0f0f) ? 0 : 4;
   b1 = (y & 0x33333333) ? 0 : 2;
   b0 = (y & 0x55555555) ? 0 : 1;
   return bz + b4 + b3 + b2 + b1 + b0;
#endif
#if 0
#define u   ' '
    static char table[64] = {
        32, 0, 1, 12, 2, 6, u, 13,     3, u, 7, u, u, u, u, 14,
        10, 4, u, u, 8, u, u, 25,     u, u, u, u, u, 25, 27, 15,
        31, 11, 5, u, u, u, u, u,       9, u, u, 24, u, u, 20, 26,
        30, u, u, u, u, 23, u, 19,       29, u, 22, 18, 28, 17, 16, u
    };
#undef  u
//    x = (x & -x) * 0x0450fbaf;  // 0x0450fbaf=17*65*655;
    x = (x & -x);
    x = (x << 4) + x;       // x = x*17;
    x = (x << 6) + x;       // x = x*65;
    x = (x << 16) - x;      // x = x*65535;
    return table[x >> 26];
#endif
#if 1
    static char table[32] = {
        0, 1, 2, 24, 3, 19, 6, 25,      22, 4, 20, 10, 16, 7, 12, 26,
        31, 23, 18, 5, 21, 9, 15, 11,   30, 17, 8, 14, 29, 13, 28, 27
    };
    if(x == 0) return 32;
    x = (x & -(int)x) * 0x04d7651f;      // 0x04d7651f=2047*5*256+1;
    return table[x >> 27];
#endif
}

寻找最左侧0值字节(大端);

// 寻找最左侧0值字节(大端);
int ZByteL(unsigned int x)
{
#if 1
    if((x >> 24) == 0) return 0;
    else if((x & 0x00ff0000) == 0) return 1;
    else if((x & 0x0000ff00) == 0) return 2;
    else if((x & 0x000000ff) == 0) return 3;
    else return 4;
#endif
#if 0
    unsigned int y;
    int n;

    // Original byte: 00 80 other;
    y = (x & 0x7f7f7f) + 0x7f7f7f7f;
    y = ~(y | x | 0x7f7f7f7f);
    n = Ntz(y) >> 3;
    return n;
#endif
#if 0
    unsigned int y;
    int t1, t2, t3, t4;

    y = (x & 0x7f7f7f7f) + 0x7f7f7f7f;
    y = y | x;              // Leading 1 on nonzero bytes;
    t1 = y >> 31;           // t1 = a;
    t2 = (y >> 23) & t1;    // t2 = ab;
    t3 = (y >> 15) & t2;    // t3 = abc;
    t4 = (y >> 7) & t3;     // t4 = abcd;
    return t1 + t2 + t3 + t4;
#endif
}

寻找最右侧0值字节(小端);

// 寻找最右侧0值字节(小端);
int ZByteR(unsigned int x)
{
#if 0
    if((x >> 24) == 0) return 3;
    else if((x & 0x00ff0000) == 0) return 2;
    else if((x & 0x0000ff00) == 0) return 1;
    else if((x & 0x000000ff) == 0) return 0;
    else return 4;
#endif
#if 1
    unsigned int y;
    int t1, t2, t3, t4;

    y = (x & 0x7f7f7f7f) + 0x7f7f7f7f;
    y = y | x;              // Leading 1 on nonzero bytes;
//    PrintBitNum(y);
    t1 = (y >> 7) & 0x01;   // t1 = d;
//    PrintBitNum(t1);
    t2 = (y >> 15) & t1;    // t2 = cd;
//    PrintBitNum(t2);
    t3 = (y >> 23) & t2;    // t3 = bcd;
//    PrintBitNum(t3);
    t4 = (y >> 31) & t3;    // t4 = abcd;
//    PrintBitNum(t4);
    return t1 + t2 + t3 + t4;
#endif
}

寻找首个给定长度的全1位串(大端);

// 寻找首个给定长度的全1位串(大端);
int Ffstr1(unsigned int x, int n)
{
#if 0
    int k, p;

    p = 0;
    while(x != 0){
        k = Nlz(x);         // Skip over initial 0's;
        x = x << k;         // (if any);
        p = p + k;
        k = Nlz(~x);        // Count first/next group of 1's;
        if(k >= n)          // If enough,
            return p;       // return;
        x = x << k;         // Not enough 1's, skip over;
        p = p + k;          // them;
    }
    return 32;
#else
    int s;
    while(n > 1){
        s = n >> 1;
        x = x & (x << s);
        n = n - s;
    }
    return Nlz(x);
#endif
}

寻找全长“全1位串”的长度;

// 寻找全长“全1位串”的长度;
int Maxstr1(unsigned int x)
{
    int k;
    for(k=0; x != 0; k++) x = x & 2*x;
    return k;
}

寻找最长“全1位串”的长度及起始位置;

// 寻找最长“全1位串”的长度及起始位置;
int Fmaxstr1(unsigned int x, int *apos)
{
    unsigned int y;
    int s;

    if(x == 0){*apos = 32; return 0;}
    y = x & (x << 1);
    if(y == 0){s = 1; goto L1;}
    x = y & (y << 2);
    if(x == 0){s = 2; x = y; goto L2;}
    y = x & (x << 4);
    if(y == 0){s = 4; goto L4;}
    x = y & (y << 8);
    if(x == 0){s = 8; x = y; goto L8;}
    if(x == 0xfff8000){*apos = 0; return 32;}
    s = 16;

L16:
    y = x & (x << 8);
    if(y != 0){s = s + 8; x = y;}
L8:
    y = x & (x << 4);
    if(y != 0){s = s + 4; x = y;}
L4:
    y = x & (x << 2);
    if(y != 0){s = s + 2; x = y;}
L2:
    y = x & (x << 1);
    if(y != 0){s = s + 1; x = y;}
L1:
    *apos = Nlz(x);
    return s;
}

寻找最短“全1位串”的长度与起始位置;

//寻找最短“全1位串”的长度与起始位置;
int Fminstr1(unsigned int x, int *apos)
{
    int k;
    unsigned int b, e;

    if(x == 0){*apos = 32; return 0;}
    b = ~(x >> 1) & x;      // 0-1 transitions;
    e = x & ~(x << 1);      // 0-1 transitions;
    for(k=1; (b&e)==0; k++) e = e << 1;
    *apos = Nlz(b & e);
    return k;
}

计算比x值大且位元1的个数相同的数;

// 计算比x值大且位元1的个数相同的数;
int Snoob(int x)
{
    unsigned int smallest, ripple, ones;
                                    // x = xxx0 1111 0000;
    smallest = x & -x;              //     0000 0001 0000;
    ripple = x + smallest;          //     xxx1 0000 0000;
    ones = x ^ ripple;              //     0001 1111 0000;
    ones = (ones >> 2) / smallest;  //     0000 0000 0111;
    return ripple | ones;           //     xxx1 0000 0111;
}

将数值上调/下调为2的已知次幂的倍数;

unsigned int Flp2(unsigned int x)
{
    x = x | (x >> 1);
    x = x | (x >> 2);
    x = x | (x >> 4);
    x = x | (x >> 8);
    x = x | (x >> 16);
    return x - (x >> 1);
}

unsigned int Clp2(unsigned int x)
{
    x = x - 1;
    x = x | (x >> 1);
    x = x | (x >> 2);
    x = x | (x >> 4);
    x = x | (x >> 8);
    x = x | (x >> 16);
    return x + 1;
}

压缩与展开;


unsigned int Compress(unsigned int x, unsigned int m)
{
#if 0
    unsigned int r, s, b;       // Result, shift, mask bit;

    r = 0;
    s = 0;
    do{
        b = m & 1;
        r = r | ((x & b) << s);
        s = s + b;
        x = x >> 1;
        m = m >> 1;
    }while(m != 0);
    return r;
#else
    // 平行后缀法;
    unsigned int mk, mp, mv, t;
    int i;

    x = x & m;              // Clear irrelevant bits;
    mk = ~m << 1;           // We will count 0's to right;

    for(i=0; i<5; i++){
        mp = mk ^ (mk << 1);            // Parallel suffix;
        mp = mp ^ (mp << 2);
        mp = mp ^ (mp << 4);
        mp = mp ^ (mp << 8);
        mp = mp ^ (mp << 16);
        mv = mp & m;                    // Bits to move;
        m = m ^ mv | (mv >> (1 << i));  // Compress m;
        t = x & mv;
        x = x ^ t | (t >> (1 << i));    // Compress x;
        mk = mk & ~mp;
    }
    return x;
#endif
}

unsigned int CompressLeft(unsigned int x, unsigned int m)
{
    // 平行后缀法;
    unsigned int mk, mp, mv, t;
    int i;

    x = x & m;              // Clear irrelevant bits;
    mk = ~m >> 1;           // We will count 0's to right;

    for(i=0; i<5; i++){
        mp = mk ^ (mk >> 1);            // Parallel suffix;
        mp = mp ^ (mp >> 2);
        mp = mp ^ (mp >> 4);
        mp = mp ^ (mp >> 8);
        mp = mp ^ (mp >> 16);
        mv = mp & m;                    // Bits to move;
        m = m ^ mv | (mv << (1 << i));  // Compress m;
        t = x & mv;
        x = x ^ t | (t << (1 << i));    // Compress x;
        mk = mk & ~mp;
    }
    return x;
}

unsigned int Expand(unsigned int x, unsigned int m)
{
    unsigned int m0, mk, mp, mv, t;
    unsigned array[5];
    int i;

    m0 = m;         // Save original mask;
    mk = ~m << 1;   // We will count 0's to right;

    for(i=0; i<5; i++){
        mp = mk ^ (mk << 1);        // Parallel suffix;
        mp = mp ^ (mp << 2);
        mp = mp ^ (mp << 4);
        mp = mp ^ (mp << 8);
        mp = mp ^ (mp << 16);
        mv = mp & m;                // Bits to move;
        array[i] = mv;
        m = (m ^ mv) | (mv >> (1 << i));    // Compress m;
        mk = mk & ~mp;
    }

    for(i=4; i>=0; i--){
        mv = array[i];
        t = x << (1 << i);
        x = (x & ~mv) | (t & mv);
    }
    return x & m0;      // Crear out extraneous bits;
}

unsigned int ExpandLeft(unsigned int x, unsigned int m)
{
    unsigned int m0, mk, mp, mv, t;
    unsigned array[5];
    int i;

    m0 = m;         // Save original mask;
    mk = ~m >> 1;   // We will count 0's to right;

    for(i=0; i<5; i++){
        mp = mk ^ (mk >> 1);        // Parallel suffix;
        mp = mp ^ (mp >> 2);
        mp = mp ^ (mp >> 4);
        mp = mp ^ (mp >> 8);
        mp = mp ^ (mp >> 16);
        mv = mp & m;                // Bits to move;
        array[i] = mv;
        m = (m ^ mv) | (mv << (1 << i));    // Compress m;
        mk = mk & ~mp;
    }

    for(i=4; i>=0; i--){
        mv = array[i];
        t = x >> (1 << i);
        x = (x & ~mv) | (t & mv);
    }
    return x & m0;      // Crear out extraneous bits;
}

分羊法(sheep and goats operation, SAG);

// 分羊法(sheep and goats operation, SAG);
#define SAG(x, m)       (CompressLeft(x, m) | Compress(x, ~m))

CRC32;


unsigned int CRC32(unsigned char *message)
{
#if 1
    // 基本CRC-32算法;
    int i, j;
    unsigned int byte, crc;

    i = 0;
    crc = 0xffffffff;
    while(message[i] != 0){
        byte = message[i];          // Get next byte;
        byte = RevBit(byte);        // 32-bit reversal;
        for(j=0; j<=7; j++){
            if((int)(crc ^ byte) < 0)
                crc = (crc << 1) ^ 0x04c11db7;
            else
                crc = crc << 1;
            byte = byte << 1;       // Ready next msg bit;
        }
        i = i + 1;
    }
    return RevBit(~crc);
#endif
#if 0
    // 每次处理一个位元;
    int i, j;
    unsigned int byte, crc, mask;

    i = 0;
    crc = 0xffffffff;
    while(message[i] != 0){
        byte = message[i];
        crc = crc ^ byte;
        for(j=7; j>=0; j--){
            mask = -(crc & 1);
            crc = (crc >> 1) ^ (0xedb88320 & mask);
        }
        i = i + 1;
    }
    return ~crc;
#endif
#if 0
    // 查表法实现CRC算法;
    int i, j;
    unsigned int byte, crc, mask;
    static unsigned int table[256];

    // Set up the table, if necessay;
    if(table[1] == 0){
        for(byte=0; byte<=255; byte++){
            crc = byte;
            for(j=7; j>=0; j--){
                mask = -(crc & 1);
                crc = (crc >> 1) ^ (0xedb88320 & mask);
            }
            table[byte] = crc;
        }
    }

    // Through with table setup, now calculate the CRC;
    i = 0;
    crc = 0xffffffff;
    while((byte = message[i]) != 0){
        crc = (crc >> 8) ^ table[(crc ^ byte) & 0xff];
        i = i + 1;
    }
    return ~crc;
#endif
}

反转位元;

// 反转位元;
// 30RISC;
unsigned int RevBit(unsigned int x)
{
    x = (x & 0x55555555) << 1 | (x >> 1) & 0x55555555;
    x = (x & 0x33333333) << 2 | (x >> 2) & 0x33333333;
    x = (x & 0x0f0f0f0f) << 4 | (x >> 4) & 0x0f0f0f0f;
    x = (x << 24) | ((x & 0xff00) << 8) | ((x >>8) & 0xff00) | (x >> 24);
    return x;
}
// shlr, 25RISC;
unsigned int KnuthRevBit(unsigned int x)
{
    unsigned int t;
    x = ROTATE_LEFT32(x, 15); // shlr(x, 15)
    t = (x ^ (x >> 10)) & 0x003f801f; x = (t | (t << 10)) ^ x;
    t = (x ^ (x >> 4)) & 0x0e038421; x = (t | (t << 4)) ^ x;
    t = (x ^ (x >> 2)) & 0x22488842; x = (t | (t << 2)) ^ x;
    return x;
}

unsigned long long KnuthRevBit(unsigned long long x)
{
    unsigned long long t;
#if 1
    // 24 RISC;
    x = (x << 32) | (x >> 32); // swap register halves.
    x = (x & 0x0001ffff0001ffffLL) << 15 | (x & 0xfffe0000fffe0000LL) >> 17; // rotate left 15.
    t = (x ^ (x >> 10)) & 0x003f801f003f801fLL;
    x = (t | (t << 10)) ^ x;
    t = (x ^ (x >> 4)) & 0x0e0384210e038421LL;
    x = (t | (t << 4)) ^ x;
    t = (x ^ (x >> 2)) & 0x2248884222488842LL;
    x = (t | (t << 2)) ^ x;
#else
    // 25 RISC;
    x = (x << 31) | (x >> 33);
    t = (x ^ (x >> 20)) & 0x00000fff800007ffLL;
    x = (t | (t << 20)) ^ x;
    t = (x ^ (x >> 8)) & 0x00f8000f80700807LL;
    x = (t | (t << 8)) ^ x;
    t = (x ^ (x >> 4)) & 0x0808708080807008LL;
    x = (t | (t << 4)) ^ x;
    t = (x ^ (x >> 2)) & 0x1111111111111111LL;
    x = (t | (t << 2)) ^ x;
#endif
    return x;
}

unsigned int RevMask(unsigned int x)
{
    static unsigned char table[256] = {
        0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
        0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
        0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
        0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
        0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
        0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
        0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
        0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
        0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
        0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
        0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
        0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
        0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
        0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
        0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
        0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
        0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
        0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
        0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
        0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
        0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
        0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
        0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
        0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
        0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
        0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
        0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
        0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
        0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
        0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
        0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
        0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
    };
    unsigned int r = 0;

    for(int i=3; i>=0; i--){
        r = (r << 8) + table[x & 0xff];
        x = x >> 8;
    }
    return r;
}

位矩阵转置;

// RISC 40 + 21 + 40
void TransPose8(unsigned char a[8], int m, int n, unsigned char b[8])
{
    unsigned long long x = 0;
    int i;

    // Load 8 bytes from the input array and pack them into x.
    for(i=0; i<=7; i++){
        x = (x << 8) | a[m*i];
    }

printf("x=0x%016llx\n", x);
    x = x & 0xaa55aa55aa55aa55LL        |
       (x & 0x00aa00aa00aa00aaLL) << 7  |
       (x >> 7) & 0x00aa00aa00aa00aaLL;
    x = x & 0xcccc3333cccc3333LL        |
       (x & 0x0000cccc0000ccccLL) << 14 |
       (x >> 14) & 0x0000cccc0000ccccLL;
    x = x & 0xf0f0f0f00f0f0f0fLL        |
       (x & 0x00000000f0f0f0f0LL) << 28 |
       (x >> 28) & 0x00000000f0f0f0f0LL;
printf("x=0x%016llx\n", x);

    // Store result into output array b.
    for(i=7; i>=0; i--){
        b[n*i] = x; x = x >> 8;
    }
}

#define TransPosMatrx8(x)   \
    x = (x & 0xaa55aa55aa55aa55LL) | ((x & 0x00aa00aa00aa00aaLL) << 7) | ((x >> 7) & 0x00aa00aa00aa00aaLL);   \
    x = (x & 0xcccc3333cccc3333LL) | ((x & 0x0000cccc0000ccccLL) << 14) | ((x >> 14) & 0x0000cccc0000ccccLL); \
    x = (x & 0xf0f0f0f00f0f0f0fLL) | ((x & 0x00000000f0f0f0f0LL) << 28) | ((x >> 28) & 0x00000000f0f0f0f0LL); 


#define SwapIntArr(a)   \
{   \
    a[0] = BLSwap32(a[0]); \
    a[1] = BLSwap32(a[1]); \
    a[2] = BLSwap32(a[2]); \
    a[3] = BLSwap32(a[3]); \
    a[4] = BLSwap32(a[4]); \
    a[5] = BLSwap32(a[5]); \
    a[6] = BLSwap32(a[6]); \
    a[7] = BLSwap32(a[7]); \
    a[8] = BLSwap32(a[8]); \
    a[9] = BLSwap32(a[9]); \
    a[10] = BLSwap32(a[10]); \
    a[11] = BLSwap32(a[11]); \
    a[12] = BLSwap32(a[12]); \
    a[13] = BLSwap32(a[13]); \
    a[14] = BLSwap32(a[14]); \
    a[15] = BLSwap32(a[15]); \
    a[16] = BLSwap32(a[16]); \
    a[17] = BLSwap32(a[17]); \
    a[18] = BLSwap32(a[18]); \
    a[19] = BLSwap32(a[19]); \
    a[20] = BLSwap32(a[20]); \
    a[21] = BLSwap32(a[21]); \
    a[22] = BLSwap32(a[22]); \
    a[23] = BLSwap32(a[23]); \
    a[24] = BLSwap32(a[24]); \
    a[25] = BLSwap32(a[25]); \
    a[26] = BLSwap32(a[26]); \
    a[27] = BLSwap32(a[27]); \
    a[28] = BLSwap32(a[28]); \
    a[29] = BLSwap32(a[29]); \
    a[30] = BLSwap32(a[30]); \
    a[31] = BLSwap32(a[31]);    \
}

// RISC 1696
void TransPose32(unsigned int a[32])
{

    int j, k;
    unsigned int m, t;

    SwapIntArr(a);

    m = 0x0000ffff;
    for (j = 16; j != 0; j = j >> 1, m = m ^ (m << j)) {
//        printf("j=%d m=%08x\n", j, m);
        for (k = 0; k<32; k = (k + j + 1) & ~j) {
//            printf("swap(a%d, a%d, %d, m);\n", k, k+j, j);
            t = (a[k] ^ (a[k + j] >> j)) & m;
            a[k] = a[k] ^ t;
            a[k + j] = a[k + j] ^ (t << j);
        }
    }

    SwapIntArr(a);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值