要将 32 位无符号转换为有符号整数,可以使用:
function convert(n)
if n >= 2 ^ 31 then
return n - 2 ^ 32
end
return n
end
没有这种比较可以做到吗?
PS:这是 Lua,因此我不能像在 C 中那样“转换”。
要将 32 位无符号转换为有符号整数,可以使用:
function convert(n)
if n >= 2 ^ 31 then
return n - 2 ^ 32
end
return n
end
没有这种比较可以做到吗?
PS:这是 Lua,因此我不能像在 C 中那样“转换”。
也许你可以通过位操作来做到这一点。在 Smalltalk 中,这将是:
^self - (2*(self bitAnd: 16r80000000))
显然 bitops 在 Lua 中不是本机的,但似乎有各种位库可用,请参阅http://lua-users.org/wiki/BitwiseOperators
一旦找到合适的 bitand 函数,就类似于
return n - bitand(n,MAXINT)*2
不是在普通的 Lua 中。您当然可以通过编写以下代码来优化求幂和 if 语句:
local MAXINT, SUBT = math.pow(2, 31), math.pow(2, 32)
function convert(n)
-- Like C's ternary operator
return (n >= MAXINT and n - SUBT) or n
end
我不知道优化 if 语句是否会对解释器有很大帮助;我认为不适合 LuaJIT;但可能是普通的Lua?
如果您真的想避免比较,请选择 C,例如(未经测试的代码!):
int convert(lua_State *L)
{
lua_pushinteger(L, (int) ((unsigned int) luaL_checklong(L, 1)));
return 1;
}
但是,堆栈开销可能会破坏目的。
微优化的任何具体原因?
编辑:我一直在考虑这个问题,这在普通的 Lua 中实际上是可能的:
local DIV, SUBT = math.pow(2, 31) + 1, math.pow(2, 32)
-- n MUST be an integer!
function convert(n)
-- the math.floor() evaluates to 0 for integers 0 through 2^31;
-- else it is 1 and SUBT is subtracted.
return n - (math.floor(n / DIV) * SUBT)
end
我不确定它是否会提高性能;除法必须比条件跳转快。然而,从技术上讲,这回答了问题并避免了比较。