2013-12-12 22 views
9

Tôi đang viết một kịch bản lệnh Lua đơn giản để tính trung bình từ một Tập hợp Sắp xếp (http://redis.io/commands/#sorted_set) trong Redis 2.8. Tập lệnh ở bên dướiCách chuyển đổi chuỗi Lua thành float

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 

Vấn đề là tập lệnh luôn trả về một số nguyên, khi kết quả phải là phao. Kết quả là sai.

$ 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 

Kết quả chính xác nên được (3,1 + 3,4975) /2.0 == 3,298

Trả lời

9

Từ documentation for EVAL:

Lua có một kiểu số duy nhất, số Lua. Không có sự phân biệt giữa số nguyên và phao. Vì vậy, chúng tôi luôn chuyển đổi số Lua thành trả lời số nguyên, xóa phần thập phân của số nếu có. Nếu bạn muốn trả về một float từ Lua, bạn nên trả về nó như một chuỗi, chính xác như Redis (ví dụ như lệnh ZSCORE).

Vì vậy, bạn nên cập nhật kịch bản của bạn, do đó bạn được trả lại float as a string:

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

Cảm ơn! "Vì vậy, chúng tôi luôn chuyển đổi số Lua thành trả lời số nguyên, xóa phần thập phân của số" - Có lý do nào cho điều đó, âm thanh hoàn toàn phản trực giác hay không. – Adil

+0

Tôi đoán số nguyên là trường hợp sử dụng phổ biến hơn so với nổi trong redis. – Azmisov

Các vấn đề liên quan