CSAPP chapter2 记录(bit_level_coding)

时间:2023-10-12 11:29:38

p_154

//5x/8
define MSB_BIT (~(~0U >> )) int mul5div8(int val)
{
int sign = (val & MSB_BIT) == MSB_BIT; //取符号位
int bias = ( + !sign) & ; int q = val >> ;
int r = val - (q << );
r = (r << ) + r + bias >> ; //向零取整
q = (q << ) + q + r; return q;
}
//整数绝对值
unsigned int abs(int val)
{
int temp = val >> ;
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 >> ;
val ^= val >> ;
val ^= val >> ;
val ^= val >> ;
val ^= val >> ; return !(x & );
}
//最右侧的1置为0
unsigned int clc_rightmost_one(unsigned int val)
{
return val & (val - );
}
//最右侧的连续1置0
unsigned int clc_rightmost_one_group(unsigned int val)
{
return (val | val - ) + & val;
}
//向零取整,除2的幂次
int divide_power2(int x, int k)
{
//注意下:对于移位运算,即使移位个数的类型为无符号类型,也不会将被移位数当成无符号类型进行移位,而是保持被移位数原来的类型属性
int bias = ( (x >> ((sizeof(int) << ) - )) & ((( << k) << ) - ) ) >> k;
return (x + bias) >> k;
}
//找到最左侧的1
unsigned int leftmost_one(unsigned int val)
{
val |= val >> ;
val |= val >> ;
val |= val >> ;
val |= val >> ;
val |= val >> ; return val - (val >> );
}
//找到最右侧的1
unsigned int rightmost_one(unsigned int x)
{
return x & (-x);
}
//找到最右侧的0
unsigned int rightmost_zero(unsigned int val)
{
return (~val) & (val + );
}
//据最右侧的1及后边的0生成掩码
unsigned int mask_rightmost_one_withzero(unsigned val)
{
return val ^ (val - );
}
//据右侧的连续的0生成掩码
unsigned int mask_rightmost_zero_group(unsigned int val)
{
return (~val) & (val - );
}
//向右传播最右侧的1
unsigned int propagate_rightmost_one(unsigned int val)
{
return val | (val - );
}