繁体   English   中英

redis lua位溢出

[英]redis lua bit overflow

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

但似乎我运气不好:

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位有符号整数)

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

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

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

另一方面...

eval 'return math.pow(2, 53) ' 0
(integer) 9007199254740992

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

PS有人会说这个逻辑移动到客户端 - 但我不能。 这篇文章相当复杂,需要与数据密切合作

看起来有点。*只能在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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM