On Sun, Sep 5, 2010 at 13:29, varol kaptan <
varol.kaptan@gmail.com> wrote:
>
> On Sun, Sep 5, 2010 at 3:42 PM, Andre Leiradella <
andre@leiradella.com>
> wrote:
>>
>> On 05/09/2010 03:15, Florian Weimer wrote:
>>>
>>> * Rob Kendrick:
>>>
>>>> On Sat, Sep 04, 2010 at 10:54:59PM +0200, Florian Weimer wrote:
>>>>
>>>>> It could be argued that tostring is lossy for tables, so it can be
>>>>> lossy for numbers, too.
>>>>
>>>> Surely converting a floating point number to a string like this is
>>>> never not going to be lossy?
>>>
>>> The default conversion in Lua (that is, tostring) is lossy,
>>> unfortunately.
>>>
>> I'm having exactly the same problem with the serialization of floats and
>> doubles to JSON (C++, not Lua.)
>>
>> If the numbers are not supposed to be hand edited, the %a format specifier
>> creates a lossless (depending on the precision used) hexadecimal ASCII
>> representation of doubles that can be transformed back to double by strtod.
>> It's a one line change in lstrlib.c, function str_format:
>>
>> case 'e': case 'E': case 'f':
>> case 'g': case 'G': case 'a': { // %a format specifier added
>> sprintf(buff, form, (double)luaL_checknumber(L, arg));
>> break;
>> }
>>
>> Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
>> > print(string.format('%.13a', 0.1)) -- 13 is large enough to represent
>> > all significand bits
>> 0x1.999999999999ap-4
>>
>> Which is 1.999999999999a * 2^-4. And tonumber already converts it back to
>> double:
>>
>> > print(tonumber('0x1.999999999999ap-4'))
>> 0.1
>>
>> Unfortunately the lexer doesn't like the hexadecimal point but patching it
>> must be easy:
>>
>> > a=0x1.999999999999a0p-4
>> stdin:1: malformed number near '.999999999999a0p'
>
> I am attaching a patch for anyone interested that does just that. Apply
> against stock 5.1.4.
>
>>
>> Doubles have 52 bits to represent the significand, so 52/4=13 in the %a
>> specifier is enough to represent all of its bits. The implicit 1 before the
>> significand (0 in denormals) is not part of the fraction so it does not
>> count in the 13 digits after the point.
>>
>> It's a shame I can't use this format in JSON, its specification doesn't
>> allow hexadecimal numbers.
>>
>> Cheers,
>>
>> Andre
>>
>
>