lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 05/09/2010 17:04, varol kaptan wrote:


On Sun, Sep 5, 2010 at 8:38 PM, HyperHacker <hyperhacker@gmail.com> wrote:
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
>>
>
>

Hm, this seems like a very useful feature. Why haven't I heard of the
%a format before?

 
C99, hence does not work in Windows.
You mean with MSVC? It does work with MinGW which uses the Win32 API instead of a POSIX layer like Cygwin.

Cheers,

Andre
 
--
Sent from my toaster.