Message-Id: <200005131046.GAA30179@delorie.com> From: "Dieter Buerssner" To: Eli Zaretskii Date: Sat, 13 May 2000 13:54:37 +0200 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Re: Math functions CC: djgpp-workers AT delorie DOT com In-reply-to: <200005122027.QAA14913@indy.delorie.com> References: <200005121101 DOT HAA05022 AT delorie DOT com> (buers AT gmx DOT de) X-mailer: Pegasus Mail for Win32 (v3.12b) Reply-To: djgpp-workers AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk On 12 May 00, at 16:27, Eli Zaretskii wrote: > > From: "Dieter Buerssner" > > Date: Fri, 12 May 2000 14:09:52 +0200 > > > > The setting of errno seems not to be required by the latest C Standard. > > C89 clearly requires it. I don't think it's wise to drop support for > C89 while adding support for C99. The code is already written, and > IMHO setting errno is a good feature: it makes error checking easy and > predictable (as opposed to using `isnan' and similar functions). Yes, I see, that it can be useful. > Anyway, the only saving would be a single integer instruction that > stores a value in errno. Unfortunately, it can be much more. You have to test the arguments for range errors, poles, and special values. Compare my 3 lines of inline assembly, with the code of log.S. Anyway, in my other mail, you can see, that I already tried to set errno. The problem are assembler only functions, where it IHMO really needs a lot of bit twiddling, that I can do much easier in C. A maybe acceptable alternative would be, to check the arguments in C code, and call then an assembler function, that does the calculation. Inline assembly unfortunately won't work in many cases. > > The checking code for the mathfunctions silently loads a NaN into the > > top of the FPU-stack, when a domain error occures. This has IHMO a > > significant disadvantage. When setting up the FPU control word, to > > get exceptions for (say) overflow, div by zero and invalid (which I > > find useful while debugging), the functions won't raise that > > exception. > > AFAIK, the latest version of GCC emit inline code for many standard > math functions. I'm positive about `sqrt' and `exp', but I'd expect > some others, like `sin', `cos', and `atan', to be handled in a similar > way. Not for exp and atan. >The inline code issues the FP instruction, and if it produces > abnormal results (as indicated by the status word), the library > function is called to handle this. Yes (unless called with -ffast-math). For sqrtl, there will also be produced inline code, but not for sinl (which is good). I even think, that the inline code for sin is questionable, because it can loose quite some precision compared to the libm version for (intermediate) large arguments. > Note that if you link against libm.a, the exceptions won't be > triggered as well. They will be triggered here. (I.e. my code snippet will trigger an exception, when linked with -lm.) > > So, I think, the easier implementation of my_log is preferrable. It > > will always return the same values, but won't set errno. > This is a step backwards, IMHO. I agree, with the errno. But I really cannot see, why the exceptions are bad. >The original math functions written > by DJ which where in use up to and including v2.02 were implemented > like you suggest. We replaced them with Eric's versions because they > complied with ANSI C while still being very fast and accurate; before > that, the only way to get ANSI behavior was to link against libm.a and > pay the price in performance. I totally agree, that Eric's functions are much better, than what was in older versions of DJGPP. I even did quite some testing with these functions, and they seem to do very well in my tests. > > Do you prefer, to not raise exceptions? > > Yes, absolutely. At least for production code, which is what libc.a > is for. Could you please explain, why you dislike the exceptions. They are all masked by default anyway (as suggested by the IEEE standards). So a "normal" user should not be able, to tell the difference. I cannot see any disadvantage. Besides the point, I made for debugging, they can also be useful in interactive numerical programs. Set a flag in a signal handler for SIGFPE, that can be checked at strategical places, outside of the "inner loop". errno won't be enough for this, because one also might want to check for division by zero (or even more sublte something like 1.0/denormal number) and more. A different approach would be, to check the FPU status word. > Please post the list of the functions, and let's talk about them. Here is a list of my source tree. Obviously, the double precision versions are not needed (many of the .s are unchanged or only slightly changed versions of DJGPP 1.x), because they are inferior, to what Eric has written. The long double versions are quite well tested for accuracy (various test programs, including comparision to 100 digit precision). The problems of old DJGPP versions of the hyperbolic functions are fixed. The first four are "fast" versions, without accurate argument reduction. _cosl.s _powl.s _sinl.s _tanl.s acos.s clex87.s fabs.s j1.c powl.c acosh.c copysgnl.c fabsl.s jn.c rint.s acoshl.c copysign.c finite.c ld1plsma.s rintl.s acosl.s cos.s finitel.c ld1psma.s scalb.s asin.s cosh.c floor.s lgamma.c scalbl.s asinh.c coshl.c floorl.s log.s setcw87.s asinhl.c cosl.c fmod.s log10.s sin.s asinl.s drem.s fmodl.s log10l.s sinh.c atan.s dreml.s frexp.c log1p.c sinhl.c atan2.s erf.c frexpl.c log1pl.c sinl.c atan2l.s exp.s gamma.c log1plsm.s sqrt.s atanh.c exp2m1ls.s getcw87.s log1psma.s sqrtl.s atanhl.c exp2m1sm.s getsw87.s log2.s tan.s atanl.s expl.s isinf.c log2l.s tanh.c cbrt.c expm1.c isinfl.c logb.s tanhl.c cbrtl.c expm1l.c isnan.c logbl.s tanl.c ceil.s expm1lsm.s isnanl.c logl.s ceill.s expm1sma.s j0.c mconsts.c -- Regards, Dieter Buerssner