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

Lars T. Kyllingstad public at kyllingen.NOSPAMnet
Wed Oct 20 08:48:28 PDT 2010


On Wed, 20 Oct 2010 15:44:48 +0000, Lars T. Kyllingstad wrote:

> On Wed, 20 Oct 2010 10:30:39 -0500, Andrei Alexandrescu wrote:
> 
>> On 10/20/10 5:32 CDT, 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 wonder what would be a sensible default. If the default for absolute
>> error is zero, then you'd have an equally odd behavior for very small
>> numbers (and most notably zero). Essentially nothing would be
>> approximately zero.
>> 
>> Andrei
> 
> 
> Well, seeing as we have now been made aware of Don's feqrel() function,
> would something like this work?
> 
>   bool approxEqual(T)(T lhs, T rhs, uint significantDigits) {
>       enum r = log(10)/log(2);
>       return feqrel(lhs, rhs) > significantDigits*r;
>   }
> 
> -Lars

FWIW, that's how you specify precision in Mathematica -- by the number of 
digits.

-Lars


More information about the Digitalmars-d mailing list