[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: why tostring for number use LUA_NUMBER_FMT "%.14g", not "%.16g" ?
- From: pulleyzzz_gmail <pulleyzzz@...>
- Date: Mon, 9 Sep 2013 10:39:13 +0800
Yes, I use tostring/tonumber for the serializing of number (include float and 52bit integer).
so, don't care the float compare, just see the big integer:
a=4222124661844650
b=tostring(a)
c=string.format('%.16g',a)
print(a==tonumber(b),a==tonumber ( c) ) --- out: false, true
for the integer, value is error.
在 2013-9-8,15:09,Coda Highland <chighland@gmail.com> 写道:
> On Sat, Sep 7, 2013 at 1:51 PM, Leo Razoumov <slonik.az@gmail.com> wrote:
>> On 9/7/13, pulleyzzz_gmail <pulleyzzz@gmail.com> wrote:
>>> for this code:
>>>
>>> a=tostring(1/3)
>>> print(1/3==tonumber(a)) -- false
>>>
>>> --if use .16g
>>>
>>> a=string.format('%.16g',1/3)
>>> print(1/3==tonumber(a)) -- true
>>>
>>
>> Changing format to "%.16g" would not solve your problem of comparing
>> floats with == operator.
>>
>> 1/3 is computed in Lua natively in binary representation.
>>
>> a=string.format('%.16g',1/3) is a binary representation converted to a
>> finite length
>> base-10 number. Very often it cannot be done without loss of accuracy.
>> Next, you are converting it to binary again with tonumber(a) which
>> causes another loss of accuracy.
>>
>> As a rule of thumb do not compare floats with == operator. It will
>> lead to subtle and
>> difficult to catch errors.
>>
>> --Leo--
>>
>
> This answer, while technically correct, is actually misguided.
>
> 1/3 == 1/3 is guaranteed to be true. It's the same expression. (1/6 +
> 1/6 == 1/3 is a different question.)
>
> But when you're discussing SERIALIZING floats, %.14g is not
> sufficient. %.16g is sufficient to uniquely identify every possible
> double-precision IEEE floating point number with a clean round trip.
>
> So there IS a valid question to be asked here: Why SHOULDN'T
> tostring() use %.16g?
>
> /s/ Adam
>