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)

Reply via email to