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

Lars T. Kyllingstad public at kyllingen.NOSPAMnet
Wed Oct 20 04:18:44 PDT 2010


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.

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?

-Lars


More information about the Digitalmars-d mailing list