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 15:30:09 浏览: 99
函数 `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` 位。
最终返回的是计算出的欧几里得距离的整数值。
需要注意的是,该函数中使用了一些位运算技巧和条件判断来提高计算效率,并且对负数进行了特殊处理。
相关问题
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; }分析下这个函数的功能
这个函数的功能是计算一个无符号整数 `_v` 的二进制表示中最高位的位置。
具体分析如下:
1. 首先,将 `_v` 的高16位与 0xFFFF0000 进行按位与操作,得到一个非零的结果时,说明 `_v` 的最高位在高16位中,将结果左移4位,并赋值给变量 `m`。
2. 然后,将 `_v` 右移 `m` 位,将结果赋值回 `_v`,并将 `m` 赋值给变量 `ret`。
3. 接下来,将 `_v` 的高8位与 0xFF00 进行按位与操作,得到一个非零的结果时,说明 `_v` 的最高位在第17-24位中,将结果左移3位,并赋值给变量 `m`。
4. 将 `_v` 右移 `m` 位,将结果赋值回 `_v`,并将 `m` 赋值给变量 `ret`。
5. 类似地,继续进行两次类似的操作,分别判断 `_v` 的最高位在第9-16位和第5-8位中,并将结果左移2位和1位,并更新 `_v` 和 `ret` 的值。
6. 最后,判断 `_v` 的最高位是否在第1-4位中,并将结果赋值给 `ret` 的最低4位。
7. 最后一步,将 `_v` 与 0x02 进行按位与操作,结果为非零时,将结果加1,并将该结果加到 `ret` 上,得到最终的结果。
综上所述,这个函数的功能是计算一个无符号整数的二进制表示中最高位的位置,并返回该位置值。
目标函数:min y 约束条件: y = 100, 0 <= x < 20 y = 60, 20 <= x < 30 y = 100, 30 <= x < 10800 x = 31 将这个模型用VB.NET调用Cplex求解
以下是用VB.NET调用Cplex求解上述模型的代码示例:
```vb.net
Imports ILOG.CPLEX
Imports System.IO
Module Module1
Sub Main()
Dim cplex As New Cplex()
' 创建变量 x 和 y
Dim x As INumVar = cplex.NumVar(0, 10800, NumVarType.Float, "x")
Dim y As INumVar = cplex.NumVar(0, 100, NumVarType.Float, "y")
' 创建约束条件
Dim c1 As ILinearNumExpr = cplex.LinearNumExpr()
c1.AddTerm(1.0, x)
cplex.AddEq(c1, 31)
Dim c2 As ILinearNumExpr = cplex.LinearNumExpr()
c2.AddTerm(1.0, y)
cplex.AddEq(c2, 100)
Dim c3 As ILinearNumExpr = cplex.LinearNumExpr()
c3.AddTerm(1.0, y)
cplex.AddLe(c3, 60)
Dim c4 As ILinearNumExpr = cplex.LinearNumExpr()
c4.AddTerm(1.0, y)
cplex.AddGe(c4, 100)
Dim c5 As ILinearNumExpr = cplex.LinearNumExpr()
c5.AddTerm(1.0, x)
c5.AddTerm(-20.0, y)
cplex.AddGe(c5, 0)
Dim c6 As ILinearNumExpr = cplex.LinearNumExpr()
c6.AddTerm(1.0, x)
c6.AddTerm(-30.0, y)
cplex.AddLe(c6, 0)
' 创建目标函数
Dim obj As ILinearNumExpr = cplex.LinearNumExpr()
obj.AddTerm(1.0, y)
cplex.AddMinimize(obj)
' 求解优化模型
If cplex.Solve() Then
Console.WriteLine("Solution status = " + cplex.GetStatus().ToString())
Console.WriteLine("Solution value = " + cplex.ObjValue.ToString())
Console.WriteLine("x = " + cplex.GetValue(x).ToString())
Console.WriteLine("y = " + cplex.GetValue(y).ToString())
Else
Console.WriteLine("The problem is infeasible or unbounded.")
End If
cplex.End()
Console.ReadKey()
End Sub
End Module
```
请注意:在使用此代码之前,您需要先安装 CPLEX 和 IBM ILOG CPLEX Optimization Studio,并将其添加到您的 VB.NET 项目中。
阅读全文