未经签名而无需比较签名

时间:2013-06-17 16:24:00

标签: optimization casting lua bit-manipulation unsigned-integer

要将32位无符号转换为有符号整数,可以使用:

function convert(n)
    if n >= 2 ^ 31 then
        return n - 2 ^ 32
    end
    return n
end

没有比较可以做到吗?

PS:这是Lua,因此我不能像C中那样“施放”。

2 个答案:

答案 0 :(得分:5)

也许你可以用位操作来做。在Smalltalk中将是:

^self - (2*(self bitAnd: 16r80000000))

显然bita在Lua中不是原生的,但似乎有各种位库可用,请参阅http://lua-users.org/wiki/BitwiseOperators

找到合适的位和功能后,就像

return n - bitand(n,MAXINT)*2

答案 1 :(得分:0)

不是简单的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

我不确定它是否会提高性能;除法必须比条件跳转更快。 但从技术上讲,这可以回答这个问题并避免比较。