redis lua位溢出

时间:2015-11-02 09:44:34

标签: lua redis overflow

我正在使用redis lua并且需要对最多53位的字段执行按位逻辑运算(redis有序集合分数的整数部分的默认长度)

但似乎我运气不好:

@Action(value = "currencies", results = {
    @Result(name = "success", 
            type = "json", 
          params = {"root","currency"})
})

似乎有点。*只能在30位上运行然后溢出(32位有符号整数)

我使用Linux 64位,redis也编译为64位。 它看起来像位库的限制:

{{3}}

  

请注意,所有位操作都返回带符号的32位数(基本原理)。   并且这些默认打印为带符号的十进制数字。

另一方面......

127.0.0.1:6379> eval 'return bit.lshift(1, 30) ' 0
(integer) 1073741824
127.0.0.1:6379> eval 'return bit.lshift(1, 31) ' 0
(integer) -2147483648

知道如何更好地克服这个问题吗?

P.S。有人会说这个逻辑移动到客户端 - 但我不能。这篇文章非常复杂,需要与数据紧密合作

1 个答案:

答案 0 :(得分:2)

  

似乎有点。*只能在30位上运行然后溢出(32位有符号整数)

不是真的。 LuaJIT的BitOp适用于32位有符号整数。这就是为什么2 ^ 31是负数的原因。 BitOp文档解释了使用signed int32而不是unsigned的原因是因为架构兼容性问题:

  

将结果类型定义为无符号数不会   跨平台安全。因此,所有位操作都被定义为返回   得到有符号32位数的范围

http://bitop.luajit.org/semantics.html

将比特运算的结果与常数进行比较时,这有时会很麻烦。在这种情况下,必须使用bit.tobit()对常量值进行标准化。例如:

> = bit.lshift(1, 31) == 2147483648
false
> = bit.lshift(1, 31) == bit.tobit(2147483648)
true

在任何情况下,LuaJIT的BitOp模块都限制为32位整数。

另一方面,如果您需要的所有按位操作都是lshiftrshift,则可以在普通Lua中对这些函数进行编码:

local function lshift(n, b)
   return n * 2^b
end

local function rshift(n, b)
   return n / 2^b
end