approxEqual() has fooled me for a long time...

so so at so.do
Wed Oct 20 05:22:24 PDT 2010


It is a long read and on the last page it says "Use fixed point or  
interval" :P

On Wed, 20 Oct 2010 14:59:54 +0300, Lars T. Kyllingstad  
<public at kyllingen.nospamnet> wrote:

> On Wed, 20 Oct 2010 13:33:49 +0200, Fawzi Mohamed wrote:
>
>> On 20-ott-10, at 13:18, Lars T. Kyllingstad wrote:
>>
>>> On Wed, 20 Oct 2010 12:57:11 +0200, Don wrote:
>>>
>>>> Lars T. Kyllingstad wrote:
>>>>> (This message was originally meant for the Phobos mailing list, but
>>>>> for
>>>>> some reason I am currently unable to send messages to it*.  Anyway,
>>>>> it's probably worth making others aware of this as well.)
>>>>>
>>>>> In my code, and in unittests in particular, I use
>>>>> std.math.approxEqual() a lot to check the results of various
>>>>> computations.  If I expect my result to be correct to within ten
>>>>> significant digits, say, I'd write
>>>>>
>>>>>  assert (approxEqual(result, expected, 1e-10));
>>>>>
>>>>> Since results often span several orders of magnitude, I usually don't
>>>>> care about the absolute error, so I just leave it unspecified.  So
>>>>> far,
>>>>> so good, right?
>>>>>
>>>>> NO!
>>>>>
>>>>> I just discovered today that the default value for approxEqual's
>>>>> default absolute tolerance is 1e-5, and not zero as one would expect.
>>>>> This means that the following, quite unexpectedly, succeeds:
>>>>>
>>>>>  assert (approxEqual(1e-10, 1e-20, 0.1));
>>>>>
>>>>> This seems completely illogical to me, and I think it should be fixed
>>>>> ASAP.  Any objections?
>>>>
>>>> I'm personally pretty upset about the existence of that function at
>>>> all.
>>>> My very first contribution to D was a function for floating point
>>>> approximate equality, which I called approxEqual. It gives equality in
>>>> terms of number of bits. It gives correct results in all the tricky
>>>> special cases. Unlike a naive relative equality test involving
>>>> divisions, it doesn't fail for values near zero. (I _think_ that's the
>>>> reason why people think you need an absolute equality test as well).
>>>> And it's fast. No divisions, no poorly predictable branches.
>>>>
>>>> Unfortunately, somebody on the ng insisted that it should be called
>>>> feqrel(). Stupidly,  I listened. And now nobody uses my masterpiece
>>>> because it has a totally sucky name.
>>
>> I use it, but I think that having *also* a function with non zero
>> absolute error is useful.
>> With more complex operations you sum, and if the expected result is 0,
>> then feqrel will consider *any* non zero number as completely wrong. For
>> example testing matrix multiplication you cannot use feqrel alone. Still
>> feqrel is a very useful primitive that I do use (thanks Don).
>>
>>> That *is* a sucky name.  Well, now that I'm aware of it, I'll be sure
>>> to
>>> check it out. :)
>>>
>>> However, I, like most people, am a lot more used to thinking in terms
>>> of
>>> digits than bits.  If I need my results to be correct to within 10
>>> significant digits, say, how (if possible) would I use feqrel() to
>>> ensure
>>> that?
>> feqrel(a,b)>33 // 10*log(10)/log(2)
>
> ...which would be the solution of
>
>   2^bits = 10^digits,
>
> I guess.  Man, I've got to sit down and learn some more about FP numbers
> one day.
>
> Thanks!
>
> -Lars


-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


More information about the Digitalmars-d mailing list