approxEqual() has fooled me for a long time...
Fawzi Mohamed
fawzi at gmx.ch
Wed Oct 20 04:33:49 PDT 2010
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)
More information about the Digitalmars-d
mailing list