CSAPP chapter2 记录(bit_level_coding)

p_154

//5x/8

define MSB_BIT (~(~0U >> 1))                                                                                       



int mul5div8(int val)

{

    int sign = (val & MSB_BIT) == MSB_BIT; //取符号位

    int bias = (7 + !sign) & 7;



    int q = val >> 3;

    int r = val - (q << 3);

    r = (r << 2) + r + bias >> 3; //向零取整

    q = (q << 2) + q + r;



    return q;

}
//整数绝对值

unsigned int abs(int val)                                                                                           

{

    int temp = val >> 31;

    return (val ^ temp) - temp; 

}

unsigned int abs(unsigned val)
{
  unsigned int sign = val >> 31;
   return (val ^ (0 - sign)) + sign;
}
对于X86与mips,上一指令更少
对于ARM,下一指令更少
//将字节的最高位视为符号位,向左扩展                                                                                

unsigned int extbyte_leftmost_one(unsigned char val)

{

    unsigned temp = val;

    return ((temp + 0X80) & 0XFF) - 0X80; 

}
//是否含有偶数个1                                                                                                   

unsigned int even_ones(unsigned int val)

{

    val ^= val >> 16;

    val ^= val >> 8;

    val ^= val >> 4;

    val ^= val >> 2;

    val ^= val >> 1;



    return !(x & 1);

}
//最右侧的1置为0                                                                                                    

unsigned int clc_rightmost_one(unsigned int val)

{

    return val & (val - 1);

}
//最右侧的连续1置0

unsigned int clc_rightmost_one_group(unsigned int val)                                                              

{

    return (val | val - 1) + 1 & val;

}
//向零取整,除2的幂次

int divide_power2(int x, int k)                                                                                     

{

//注意下:对于移位运算,即使移位个数的类型为无符号类型,也不会将被移位数当成无符号类型进行移位,而是保持被移位数原来的类型属性

    int bias = ( (x >> ((sizeof(int) << 3) - 1)) & (((1 << k) << 1) - 1) ) >> k; 

    return (x + bias) >> k;

}
//找到最左侧的1

unsigned int leftmost_one(unsigned int val)

{

    val |= val >> 1;

    val |= val >> 2;

    val |= val >> 4;

    val |= val >> 8;

    val |= val >> 16;



    return val - (val >> 1);

}
//找到最右侧的1                                                                                             

unsigned int rightmost_one(unsigned int x)

{

    return x & (-x); 

}
//找到最右侧的0

unsigned int rightmost_zero(unsigned int val)

{

    return (~val) & (val + 1);

}
//据最右侧的1及后边的0生成掩码                                                                                      

unsigned int mask_rightmost_one_withzero(unsigned val)

{

    return val ^ (val - 1);

}
//据右侧的连续的0生成掩码                                                                                        

unsigned int mask_rightmost_zero_group(unsigned int val)

{

    return (~val) & (val - 1);

}
//向右传播最右侧的1                                                                                                 

unsigned int propagate_rightmost_one(unsigned int val)

{

    return val | (val - 1);

}

 

你可能感兴趣的:(level)