Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a Lua string to float

Tags:

redis

lua

I am writing a simple Lua script to calculate a median from a Sorted Set (http://redis.io/commands/#sorted_set) within Redis 2.8. The script is below

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

The problem is the script always returns an integer, when the result should be a float. The result is wrong.

$ 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

The correct result should be (3.1 + 3.4975)/2.0 == 3.298

like image 845
Adil Avatar asked Dec 12 '13 12:12

Adil


People also ask

Can you convert string to float?

We can convert a string to float in Python using float() function. It's a built-in function to convert an object to floating point number. Internally float() function calls specified object __float__() function.

What converts the string value into float?

We can convert String to float in java using Float. parseFloat() method.

Is Lua a float?

Float isn't basic type of values in Lua, so function type() return only number. If i remember correctly, all numbers are floating point in Lua. Integers are only floating point numbers without the decimals.

How do you change a string to an int in Lua?

You can convert strings to numbers using the function tonumber() . This takes a string argument and returns a number.


1 Answers

From the documentation for EVAL:

Lua has a single numerical type, Lua numbers. There is no distinction between integers and floats. So we always convert Lua numbers into integer replies, removing the decimal part of the number if any. If you want to return a float from Lua you should return it as a string, exactly like Redis itself does (see for instance the ZSCORE command).

Therefore, you should update your script so you are returning the float as a string:

return tostring((tonumber(vals[1]) + tonumber(vals[2]))/2.0)
like image 160
Tim Cooper Avatar answered Oct 18 '22 09:10

Tim Cooper