On Wed, 20 Oct 2010 13:33:49 +0200, Fawzi Mohamed wrote: > 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)
...which would be the solution of 2^bits = 10^digits, I guess. Man, I've got to sit down and learn some more about FP numbers one day. Thanks! -Lars