2013-12-12 37 views
9

我正在編寫一個簡單的Lua腳本來計算Redis 2.8中Sorted Set(http://redis.io/commands/#sorted_set)的中位數。腳本低於如何將Lua字符串轉換爲浮點數

local cnt = redis.call("ZCARD", KEYS[1]) 

if cnt > 0 then 
     if cnt%2 > 0 then 
       local mid = math.floor(cnt/2) 
       return redis.call("ZRANGE", KEYS[1], mid, mid) 
     else 
       local mid = math.floor(cnt/2) 
       local vals = redis.call("ZRANGE", KEYS[1], mid-1, mid) 
       return (tonumber(vals[1]) + tonumber(vals[2]))/2.0 
     end 
else 
     return nil 
end 

問題是腳本總是返回一個整數,當結果應該是一個浮點數時。結果是錯誤的。

$ redis-cli zrange floats 0 100 
1) "1.1" 
2) "2.1" 
3) "3.1" 
4) "3.4975" 
5) "42.63" 
6) "4.1" 

$ redis-cli EVAL "$(cat median.lua)" 1 floats 
(integer) 3 

正確的結果應爲(3.1 + 3.4975)/2.0 == 3.298

回答

9

documentation for EVAL

lua有一個單一的數值類型,Lua的號碼。整數和浮點數之間沒有區別。所以我們總是將Lua數字轉換爲整數回覆,如果有的話刪除數字的小數部分。 如果你想從Lua返回一個浮點數,你應該像字符串那樣返回它,就像Redis本身一樣(參見例如ZSCORE命令)。

因此,應使你返回float as a string更新腳本:

return tostring((tonumber(vals[1]) + tonumber(vals[2]))/2.0) 
+0

謝謝! 「所以我們總是將Lua數字轉換爲整數回覆,刪除數字的小數部分」 - 這是否有任何理由,聽起來完全違反直覺。 – Adil

+0

我猜整數是比redis中的浮點數更常見的用例。 – Azmisov