Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!ucsd!network.ucsd.edu!celit!ps From: ps@fps.com (Patricia Shanahan) Newsgroups: comp.std.c Subject: Re: Questions about NCEG Message-ID: <8949@celit.fps.com> Date: 5 Jun 90 15:44:27 GMT References: <8846@celit.fps.com> <13038@smoke.BRL.MIL> <8924@celit.fps.com> <1990Jun5.024808.14003@twinsun.com> Sender: daemon@fps.com Reply-To: ps@fps.com (Patricia Shanahan) Organization: FPS Computing Inc., San Diego CA Lines: 124 I am actually replying to two articles together. In article <1990Jun5.024808.14003@twinsun.com> eggert@twinsun.com (Paul Eggert) writes: >Patricia Shanahan writes: > > A truly logical high level language use of IEEE 754 would have to make > explicit allowance for the possibility that "x > y" is neither true nor > false, but meaningless because x and y are not ordered relative to each > other. > >In IEEE 754, x>y is always either true or false, and is never ``meaningless''. >A high level language can thus treat x>y like any other formula. >Granted, x>y differs from !(x<=y) when either x or y is not a number. Arbitrarily treating relational operations between unordered floats as returning false is certainly one way of handling them. Because of exactly the point you make about the difference between x>y and !(x<=y) I do not consider it a truly logical solution. Suppose I have an if(x>y)then A else B; construct, and in code block B I assumed x<=y, because at the time I wrote it I thought floats were ordered, so !(x>y) implied (x<=y). Should block B be executed if x and y are unordered? Remember, I may have selected which way round to run the test on grounds of program readability. I could equally well have coded it as if(x<=y)then B else A;, and I won't really like it if they give different results. The real problem with treating relations between unordered floats as being inherently false is in the case when the contribution of some NaN/Infinity results to the final result of the program is limited to controlling the flow of program execution. In that case you could get a meaningless output, that does not have any NaN/Infinity results printed. In article <3158@goanna.cs.rmit.oz.au> ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes: > Pop! (That was a credibility bubble bursting.) > The comparisons >, >=, <, and <= are required by IEEE 754 > to return true or false in the cases where you would expect > them to return true or false, and when it is not possible > to determine the ordering (e.g. Infinity < Infinity) the > IEEE 754 standard requires an exception. A program that uses > IEEE 754 arithmetic *CAN* rely on x > y being either true or > false. The standard also recommends providing _additional_ operators > (e.g. for C we might have !> meaning less, equal, or unordered), but > that's only a recommendation, not a requirement. > So IEEE 754 arithmetic does _exactly_ what you're asking for. Although I have said a lot about what I think a truly consistent implementation of the idea of NaN's and infinities in a high level language would have to do, I have not actually said anything about what IEEE 754 itself said on the subject. That is deliberate, because I do not have a copy of the standard in front of me and it is several years since the last time I read it all the way through. I do not claim to be an expert on what IEEE 754 says. My only real interest in this (other than curiosity) is that any extensions to C or Fortran for exposing IEEE 754 at the user level should be clean, robust, and consistent. Treating unordered comparisons as a trap seems more reasonable to me than Paul Eggert's statement that they should be treated as false. The only problem is that it is inconsistent with what seems to be the objective of delaying error reports to final output. I think my own preference would be to treat unordered comparison as an error and trap it, unless the program (through some new high level language construct) indicated what should be done with the unordered case. For example, one could add an additional clause to the traditional if-then-else, with the option of combining the additional clause with one of the cases. if(x>y) then{ /* code for x > y case */ } else{ /* cose for x <= y case */ } unordered{ /* give up gracefully, without taking a trap.*/ } if(x>y) then{ /* code for x > y case */ } else-unordered{ /* code for (x <= y) and unordered cases */ } This type of structure, combined with a trap on unordered comparison if no unordered clause was specified, would let the programmer control the treatment of unordered comparisons in a logical fashion. Incidentally, just as a matter of curiosity, if any of you have a copy of IEEE 754 handy, which does it say? Treat unordered comparisons as traps, unless a special operator is used to handle them, or treat all unordered relations as false. Although I am interested in whether it is possible to construct a set of extensions to a high level language that will provide truly consistent, logical, support for IEEE 754, I am still very dubious about whether the number of programs that would benefit would be sufficient, compared to the number for which taking a trap and core dump at the first arithmetic exception would be the right solution, to justify the effort. The biggest advantage I can see to all this, if it can be made consistent, is in optimization and vectorization. Currently we have to go to great lengths to avoid calculating a result if the result is not required by the program and its calculation could cause a trap. For example, consider a loop invariant but conditionally executed divide. It would make some optimizations easier if everything could be calculated and if it was not needed it just gets thrown away. -- Patricia Shanahan ps@fps.com uucp : ucsd!celerity!ps phone: (619) 271-9940