lua - redis lua位溢出

标签 lua redis 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

好像bit.*只能操作30位然后溢出(32位有符号整数)

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

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

Note that all bit operations return signed 32 bit numbers (rationale). And these print as signed decimal numbers by default.

另一方面...

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

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

附言有人会说将此逻辑移至客户端 - 但我不能。作品比较复杂,需要和数据紧密配合

最佳答案

It seems bit.* can operate only on 30 bits and then overflows(32 bit signed integer)

不是真的。 LuaJIT 的 BitOp 适用于 32 位有符号整数。这就是为什么 2^31 是负数的原因。 BitOp 文档解释说,使用带符号的 int32 而不是未签名的原因是因为体系结构兼容性问题:

Defining the result type as an unsigned number would not be cross-platform safe. All bit operations are thus defined to return results in the range of signed 32 bit numbers

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

关于lua - redis lua位溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33474705/

相关文章:

loops - 如何在 Lua 代码中进行无限循环?

jquery - 如何清除溢出 :hidden? 的行内 block 元素的底部边距

css 溢出和 margin-left

lua - 将元素的频率计入Lua中的数组

c++ - Lua 元事件参数顺序

python - 在python Flask(不是Django!)上完成 celery 工作后如何重定向

redis - 获取错误 redis.clients.jedis.exceptions.JedisMovedDataException : MOVED

memory-management - Redis:在不重启redis的情况下释放used_memory_rss

css - 如何在 flexbox 容器具有指定高度时滚动嵌套的 flexbox 子项

module - 如何组织 Lua 模块路径并编写 "require"调用而不失去灵活性?