redislua位溢出
我正在使用redis lua,需要对最多53位的字段执行逐位逻辑操作(redis ordered set score整数部分的默认长度) 但我似乎运气不好:redislua位溢出,lua,redis,overflow,Lua,Redis,Overflow,我正在使用redis lua,需要对最多53位的字段执行逐位逻辑操作(redis ordered set score整数部分的默认长度) 但我似乎运气不好: 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 似乎位。*只能在30位上操作,然后溢出
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
似乎位。*只能在30位上操作,然后溢出(32位有符号整数)
我使用的是64位Linux,redis也编译为64位。
这似乎是位库的一个限制:
请注意,所有位操作都返回有符号的32位数字(基本原理)。
默认情况下,这些数字打印为带符号的十进制数字
另一方面
eval 'return math.pow(2, 53) ' 0
(integer) 9007199254740992
你知道如何更好地克服这个问题吗
另外,有人会说把这个逻辑转移到客户身上,但我不能。这一部分相当复杂,需要与数据密切配合
似乎位。*只能在30位上操作,然后溢出(32位有符号整数)
不是真的。LuaJIT的BitOp处理32位有符号整数。这就是为什么2^31是负数的原因。BitOp文档解释了使用已签名int32而非未签名的原因是架构兼容性问题:
不允许将结果类型定义为无符号数
跨平台安全。因此,所有位操作都定义为返回
结果在有符号32位数字的范围内
当将位运算的结果与常数进行比较时,这有时会很麻烦。在这种情况下,有必要使用bit.tobit()
规范化常量值。例如:
> = bit.lshift(1, 31) == 2147483648
false
> = bit.lshift(1, 31) == bit.tobit(2147483648)
true
在任何情况下,LuaJIT的BitOp模块都限制为32位整数
另一方面,如果您需要的所有按位操作都是lshift
和rshift
,则可以用普通Lua对这些函数进行编码:
local function lshift(n, b)
return n * 2^b
end
local function rshift(n, b)
return n / 2^b
end
好吧,我发现了这一点:非常糟糕而且速度很慢,但看起来redis让我别无选择:(对于那些有兴趣添加redis链接的人来说:关于使用简单数学进行轮班的好提示!允许我清除丑陋的低/高字实现,并使代码更快;)