lua-users home
lua-l archive

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


On 9/9/2013 10:39 AM, pulleyzzz_gmail wrote:
> 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.

It's 16 digits my friend... Do you really have an app that use 16
digit integers? If I have code that need 16 digits of precision, I
would not have considered using tostring() to save and load those
numbers at all.

Pick any other more robust method. Why waste time on trying to
ascertain if tostring() is reliable in all such situations?

> 在 2013-9-8,15:09,Coda Highland 写道:
> 
>> On Sat, Sep 7, 2013 at 1:51 PM, Leo Razoumov wrote:
>>> On 9/7/13, pulleyzzz_gmail 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

-- 
Cheers,
Kein-Hong Man (esq.)
Kuala Lumpur, Malaysia