approxEqual() has fooled me for a long time...
Lars T. Kyllingstad
public at kyllingen.NOSPAMnet
Wed Oct 20 08:44:48 PDT 2010
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
More information about the Digitalmars-d
mailing list