X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f Date: Mon, 16 Feb 2004 14:45:00 -0600 From: Eric Rudd Subject: Re: C99 Functions Under Development and Checkout In-reply-to: To: djgpp-workers AT delorie DOT com Message-id: <40312BCC.1080507@cyberoptics.com> Organization: CyberOptics MIME-version: 1.0 Content-type: text/plain; charset=ISO-8859-1; format=flowed Content-transfer-encoding: 7bit X-Accept-Language: en,pdf User-Agent: Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.5) Gecko/20030925 References: X-MailScanner-Information: Please contact the ISP for more information X-MailScanner: Found to be clean 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 Kbwms AT aol DOT com wrote: >Is it worth the effort to fix these anomalies? > >KB Williams > > ------------------------------------------------------------------------- > B L U N D E R S C O M M I T T E D B Y F U N C T I O N S I N L I B C > ------------------------------------------------------------------------- > > This whole topic is really depressing, since these were not careless oversights, but rather philosophical differences: when I wrote these functions I carefully considered what would be the consequences of various types of behaviors for exceptional inputs. Thus, since an argument of NaN is outside the mathematical domain of definition of a function, I concluded that warning the caller by setting errno to EDOM was the prudent thing to do. Similarly, atan(+Inf,+Inf) is not defined in the mathematical sense, so I return NaN and EDOM there, as well. Then came C99, which stipulated, for instance, that atan(+Inf,+Inf) = pi/4. This is tantamount to saying that Inf/Inf = 1. I made public objections to some of these things when C99 was out for review, but the C99 committee neither changed the draft standard nor gave a significant explanation of why it kept things as they were. Thus, one could as well speak of "Blunders committed by IEEE 754 and C99". >Function | Calling |Result | Errno | Floating Point| >Name | Parameters |Expected, Actual | Expected, Actual | Exceptions | >----------|------------|------------------|-------------------|---------------| >pow | -0.0, -9.0 | -0.0 +0.0 | (none) (none) | | > > I do know that my endurance gave out somewhere in sorting out the 50 or so special cases in pow(), so some of the signs of zero and infinity may be incorrect. However, the above example would have represented a more substantive error, so I ran my pow() just now and got pow(-0.0, -9.0) = Inf, as one would expect, rather than 0. I don't have the energy or patience to "fix" these routines to produce results that I consider mathematically indefensible, in spite of the fact that in most cases the C99 behavior would actually simplify the routines, since the coprocessor already implements some of these strange standards. For instance, fpatan with arguments of +Inf and +Inf does indeed return pi/4. I went to great lengths to efficiently filter out these special cases, in order to get the behavior classified in the table as "blunders" ;-) In practical terms, I suppose that none of this is very important, since generally one attempts to avoid these exceptional arguments, precisely because their effects are not consistent from system to system. There is another reason for avoiding them: on the Pentium 4, the coprocessor handles NaNs, etc. through an exception mechanism that is as much as 300 times slower than normal execution. When I run my 2-D FFT routines, the most obvious indication that I have a stray NaN in the array is an agonizingly-slow execution, since the NaN rapidly infests the entire array. -Eric Rudd