int qr_ilog(unsigned _v) { int ret; int m; m = !!(_v&0xFFFF0000) << 4; _v >>= m; ret = m; m = !!(_v&0xFF00)<<3; _v >>= m; ret |= m; m = !!(_v&0xF0)<<2; _v >>= m; ret |= m; m = !!(_v&0x0C)<<1; _v >>= m; ret |= m; ret |= !!(_v&0x02); return ret + !!_v; } #define QR_MAXI(_a, _b) ((_a)-((_a)-(_b)&-((_b)>(_a)))) unsigned qr_ihypot(int _x, int _y) { unsigned x; unsigned y; int mask; int shift; int u; int v; int i; x= _x= abs(_x); y= _y= abs(_y); mask = -(x>y) & (_x^_y); x ^= mask; y ^= mask; _y ^= mask; shift = 31 - qr_ilog(y); shift = QR_MAXI(shift, 0); x = (unsigned) ((x<<shift) * 0x9B74EDAAULL >> 32); _y = (int) ((_y<<shift) * 0x9B74EDA9LL >> 32); u = x; mask = -(y < 0); x += _y + mask^mask; _y -= u + mask^mask; u = x + 1>>1; v = _y + 1>>1; mask = -(_y < 0); x += v + mask^mask; _y -= u + mask^mask; for(i=1; i<16; i++) { int r; u = x + 1>>2; r = (1<<2 * i) >> 1; v = _y + r>>2 * i; mask = -( _y < 0); x += v + mask^mask; _y = _y - (u + mask^mask) << 1; } return x + ((1U << shift) >> 1) >> shift; } 分析下qr_ihypot函数的功能
时间: 2024-04-19 12:30:09 浏览: 116
函数 `qr_ihypot` 实现的是计算两个整数 `_x` 和 `_y` 的欧几里得距离(hypotenuse)。具体功能分析如下:
1. 将 `_x` 和 `_y` 的绝对值分别赋值给 `x` 和 `y`。
2. 计算 `mask`,该值为一个掩码,用于判断 `_x` 和 `_y` 的大小关系。
3. 根据掩码 `mask` 对 `x`、`y` 和 `_y` 进行异或操作,实现交换 `_x` 和 `_y` 的值,使得 `x` 始终表示较大的数。
4. 计算 `shift`,该值表示将 `y` 左移的位数,使得 `y` 的最高位对齐到最高位。
5. 将 `x` 左移 `shift` 位后乘以一个固定的常数,并将结果右移32位,得到新的 `x`。
6. 将 `_y` 左移 `shift` 位后乘以一个固定的常数,并将结果右移32位,得到新的 `_y`。
7. 根据条件判断和掩码,将 `x` 和 `_y` 进行加减运算,得到新的 `x` 和 `_y`。
8. 使用循环进行迭代计算,每次迭代都将 `x` 和 `_y` 进行加减运算,并更新为新的值,直到迭代次数达到16次。
9. 最后,将 `x` 加上一个偏移值,然后右移 `shift` 位。
最终返回的是计算出的欧几里得距离的整数值。
需要注意的是,该函数中使用了一些位运算技巧和条件判断来提高计算效率,并且对负数进行了特殊处理。
阅读全文