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: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".

Adding lhs and rhs changes the interpretation of epsilon by an order
of magnitude, and if lhs and rhs are so close to equal that the
epsilon comparison comes into play at all then your choice of which
argument to multiply by is irrelevant.

/s/ Adam