2013-12-12 35 views
9

Redis 2.8のSorted Set(http://redis.io/commands/#sorted_set)から中央値を計算する簡単なLuaスクリプトを作成しています。スクリプトは次のとおりです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 == documentation for EVALから3.298

答えて

9

Luaは単一の数値型、Luaの番号を有しています。整数と浮動小数点の区別はありません。だから私たちは常にルアの数値を整数の返り値に変換し、もしあれば数値の小数部分を削除します。 Luaから浮動小数点数を返す場合は、文字列を返す必要があります。これは、Redis自体とまったく同じです(たとえば、ZSCOREコマンドを参照してください)。あなたがfloat as a stringを戻ってきているよう

したがって、あなたはあなたのスクリプトを更新する必要があります

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

ありがとう! "私たちは常にルアの数字を整数の返信に変換し、数字の小数部分を取り除いています" - その理由は何か、完全に直感的ではないと思いますか? – Adil

+0

私は、整数はレディスの浮動小数点数よりも一般的なユースケースだと思います。 – Azmisov

関連する問題