www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2003/08/28/10:56:09

Date: Thu, 28 Aug 2003 09:38:57 -0500
From: Eric Rudd <rudd AT cyberoptics DOT com>
Subject: Re: Arithmetic Exceptions in C99
In-reply-to: <200308272025.h7RKPrFT003625@speedy.ludd.luth.se>
To: djgpp-workers AT delorie DOT com
Message-id: <3F4E1401.1020602@cyberoptics.com>
Organization: CyberOptics
MIME-version: 1.0
X-Accept-Language: en,pdf
User-Agent: Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.3) Gecko/20030312
References: <200308272025 DOT h7RKPrFT003625 AT speedy DOT ludd DOT luth DOT se>
X-MailScanner-Information: Please contact the ISP for more information
X-MailScanner: Found to be clean
X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id h7SEu5t01029
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

ams AT ludd DOT luth DOT se wrote:

>>||||||which suggests to me that SIGFPE should not be set by the math 
>>    
>>
>(What do the pipes ("|") do there?)
>
The pipes were put there by my GUI E-mail client without my knowledge or 
approval. They were evidently related to cutting and pasting from the 
PDF document.

>I think that paragraph only applies to the valid input
>arguments. I. e. if you give values which are not valid input, this
>paragraph have no bearing, i. e. exception is ok.
>
I saw no qualification on the statement in 7.12.1, so I read it as 
applying to all representable arguments. There really wouldn't be much 
point in stating that no exception should occur for sensible arguments 
-- you wouldn't expect an exception to occur, anyway. The interesting 
question is what happens for (to take your example) asin(2.0).

There is good reason not to "generate externally visible exceptional 
conditions", since they might make error recovery impossible. The notion 
-- which I tried to follow in my libc math functions -- was that no 
matter what argument you fed to them, they would come back with some 
result, possibly setting errno. For instance, if you call atan2(0., 0.), 
it tests for that special case, returns with NaN, and sets errno to 
EDOM. If this were not done, an actual attempted division by zero might 
well crash the program (depending on the FPU exception mask in the 
control word), preventing recovery.

>However I don't quite see how my reasoning would legitimise raising an
>exception on overflow, underflow etc. Are values that cause overflow
>not "representable values of its [the function's] input arguments"?
>
On a Control Data computer I used a long time ago, there were certain 
bit patterns that were illegal for floating point numbers. If you tried 
loading such numbers into the FPU, an exception was generated and the 
program crashed. I think that's an example of what C99 means by 
"non-representable value". On the DJGPP platform, I don't think that 
there are any non-representable values -- they all print out as a 
number, inf, or NaN without causing a crash.

>>straighten me out, but I thought that "exception" in the context of C99 
>>had to do with setting errno, rather than a low-level processor state, 
>>as it seems to imply in Annex F.  Perhaps this would be a good question 
>>for comp.std.c.    
>>
>What text in C99 says "raising an exception" == "errno = <some
>number>;" to you?
>
Part of the problem is that C99 never satisfactorily defines 
"exception". Reading between the lines in footnote 178 in clause 7.6.2.2 
(bear in mind that the footnotes are informative, not normative), it 
appears that "exception" is intended to be an FPU processor exception, 
as described by Intel, but I've searched in vain for a normative 
definition. Of course, C99 can't talk about processor specifics; it 
would instead talk of the consequences of the exception visible to the 
program.

Furthermore, there seem to be two parallel mechanisms for handling 
errors in C99. In my earlier reply, I suppose that I was still thinking 
of C90, where only the errno mechanism existed. See 7.12.1, paragraph 2:

    2 For all functions, a domain error occurs if an input argument is
    outside the domain over
    which the mathematical function is defined. The description of each
    function lists any
    required domain errors; an implementation may define additional
    domain errors, provided
    that such errors are consistent with the mathematical definition of
    the function.194) On a
    domain error, the function returns an implementation-defined value;
    if the integer
    expression math_errhandling & MATH_ERRNO is nonzero, the integer
    expression
    errno acquires the value EDOM; if the integer expression
    math_errhandling &
    MATH_ERREXCEPT is nonzero, the ‘‘invalid’’ floating-point exception
    is raised.

>Perhaps somebody (you?) should ask for clarification on comp.std.c.
>
I'll do that, though I've learned from experience that one needs to get 
one's ducks very well in a row before posting to that group. It's not 
clear to me whether the errno mechanism is a legacy feature that's only 
retained for compatibility, or if it is intended for apps to be able to 
use both mechanisms. (Errno is not required to be set at all -- see 
7.3.2.) Also see C99 7.5, paragraph 3. I'll try to quote it here; I hope 
I don't get pipes again:

    The value of errno is zero at program startup, but is never set to
    zero by any library
    function.170) The value of errno may be set to nonzero by a library
    function call
    whether or not there is an error, provided the use of errno is not
    documented in the
    description of the function in this International Standard.

>>To cause the math functions to set SIGFPE, where they previously did 
>>not, could break existing code.    
>>
>Again, how do you _set_ SIGFPE? I thought you raised it, i. e. calling
>the signal hander somehow.
>
I was sloppy in my terminology. I should have said "raised" SIGFPE.

>The math functions shouldn't raise SIGFPE unless something goes wrong.
>
By "something goes wrong", do you mean "an unreasonable argument was 
passed", or do you mean "a bug in the math functions caused a problem"?

>The answer is: as Annex F is normative and we want to comply to C99,
>yes. (When we reach that status is a different story.)
>
The material in Annex F needs to be implemented only if __STDC_IEC_559__ 
is defined. Some older processors make compliance with Annex F very 
difficult, so compilers for such machines would probably not define 
__STDC_IEC_559__. The x87 FPU mostly complies with IEC 60559, so a 
compiler written from scratch for the x87 FPU could easily comply.

Whether it is worthwhile (or even desirable) to re-write the existing 
math routines to comply with IEC 60559/Annex F is another matter 
entirely. As I have pointed out before, several features of Annex F are 
contrary to long-accepted rules of mathematics. For instance, 0./0. is 
normally expected to produce a NaN, but according to F.9.1.4, computing 
atan2(0., 0.) returns 0. without a floating-point exception, and 
atan2(+inf, +inf) returns pi/4, even though inf/inf = NaN in normal 
arithmetic.

-Eric Rudd
rudd AT cyberoptics DOT com

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019