[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: How to extract a floating point number locale-independantly
- From: Daurnimator <quae@...>
- Date: Thu, 28 Apr 2016 17:53:37 +1000
On 27 April 2016 at 04:21, Roberto Ierusalimschy <roberto@inf.puc-rio.br> wrote:
>> Doesn't it get called once per floating point number encountered while lexing?
>
> No; it caches the 'decpoint' in the 'decpoint' field. It only calls
> 'trydecpoint' (and then 'lua_getlocaledecpoint') if the conversion
> fails *after* replacing the dot with the cached 'decpoint'.
>
>
>> I guess you could do something like:
>>
>> local function safe_tonumber(s, b)
>> if b ~= nil then
>> return tonumber(s, b)
>> else
>> local func = load("return " .. s)
>> if not func then return nil end
>> return func()
>> end
>> end
>>
>> Which is slightly less bad than the example earlier that uses setlocale.
>> But still.... I consider this an issue with lua.
>
> This seems quite inefficient.
>
> Couldn't you do what Lua does? Something along these lines:
>
> local function safe_tonumber(s)
> local locale_dec_point = string.sub(tostring(1.1), 2, 2)
> s = string.gsub(s, "%.", locale_dec_point)
> return tonumber(s)
> end
>
> (You might try to avoid computing 'locale_dec_point' every time,
> doing what Lua does: cache its result once and update when conversion
> fails...)
>
> -- Roberto
>
Today I was reading through dkjson and found it does what you said (so
at least I'm not the first person to run into this):
https://github.com/LuaDist/dkjson/blob/746c00a27fdf5f8c77d735a4490f83040c4434c2/dkjson.lua#L170
-- locale independent num2str and str2num functions
local decpoint, numfilter
local function updatedecpoint ()
decpoint = strmatch(tostring(0.5), "([^05+])")
-- build a filter that can be used to remove group separators
numfilter = "[^0-9%-%+eE" .. gsub(decpoint,
"[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0") .. "]+"
end
updatedecpoint()
local function num2str (num)
return replace(fsub(tostring(num), numfilter, ""), decpoint, ".")
end
local function str2num (str)
local num = tonumber(replace(str, ".", decpoint))
if not num then
updatedecpoint()
num = tonumber(replace(str, ".", decpoint))
end
return num
end