簡體   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