Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
redislua位溢出_Lua_Redis_Overflow - Fatal编程技术网

redislua位溢出

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位上操作,然后溢出

我正在使用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位上操作,然后溢出(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链接的人来说:关于使用简单数学进行轮班的好提示!允许我清除丑陋的低/高字实现,并使代码更快;)