Как преобразовать строку Lua в float

Я пишу простой скрипт Lua для вычисления медианы из отсортированного набора (http://redis.io/commands/#sorted_set) в пределах Redis 2.8. Скрипт находится ниже

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

проблема в том, что скрипт всегда возвращает целое число, когда результатом должен быть float. Результат неправильный.

$ 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

1 ответов


С документация EVAL:

Lua имеет один числовой тип, номера Lua. Нет различия между целыми числами и поплавками. Поэтому мы всегда преобразуем числа Lua в целочисленные ответы, удаляя десятичную часть числа, если таковая имеется. если вы хотите вернуть поплавок из Lua, вы должны вернуть его в виде строки, точно так же, как и сам Redis (см., например, команду ZSCORE).

таким образом, вы следует обновить скрипт, чтобы вы возвращали float как строку:

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