lua-users home
lua-l archive

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


On Sun, Aug 18, 2013 at 4:33 PM, Leo Razoumov <slonik.az@gmail.com> wrote:
> On 8/18/13, Coda Highland <chighland@gmail.com> wrote:
>> On Sun, Aug 18, 2013 at 4:09 PM, Leo Razoumov <slonik.az@gmail.com> wrote:
>>> On 8/9/13, Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> wrote:
>>>>> function float_equal(lhs, rhs, epsilon)
>>>>>     return math.abs(lhs - rhs) < epsilon
>>>>> end
>>>>
>>>> As mentioned before, if you have to do this, you need to use *relative*
>>>> error,
>>>> not absolute error:
>>>>       return math.abs(lhs - rhs) < epsilon*rhs
>>>>
>>>
>>> The code above is incorrect for rhs <= 0.
>>>
>>> It is better to try the following (untested):
>>>
>>> function float_equal(lhs, rhs, epsilon)
>>>     local abs= math.abs
>>>     epsilon  = epsilon or 1E-12
>>>     return abs(lhs - rhs) <= epsilon * (abs(lhs) + abs(rhs))
>>> end
>>>
>>> This implementation handles correctly the cases when one or both
>>> numbers are zero or negative,
>>>  and, (the added bonus) the function is symmetrical w.r.t. lhs<->rhs
>>> substitutions.
>>>
>>> --Leo--
>>>
>>
>> Actually, the correction is simply to use "epsilon * abs(rhs)" instead
>> of "epsilon * rhs".
>>
>
> No, expression
>     return abs(lhs - rhs) <= epsilon * abs(rhs)
> does not handle the case of rhs=0.
> E.g.: epsilon=1E-12; lhs= 1E-16; rhs=0;
>
> --Leo--
>

Hmm. That's a good point on the degenerate case, but at THAT point I
would use an if statement for rhs == 0.0 rather than trying to bake it
into the expression -- perhaps "if rhs == 0.0 then return abs(lhs) <=
epsilon end".

/s/ Adam