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