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);
}

 

posted on 2013-07-13 12:33  阿加  阅读(613)  评论(0编辑  收藏  举报

导航