Path: utzoo!utgpu!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!cornell!uw-beaver!teknowledge-vaxc!sri-unix!quintus!ok From: ok@quintus.uucp (Richard A. O'Keefe) Newsgroups: comp.lang.fortran Subject: Re: .GT. is not transitive Keywords: interest amusement floating-point Message-ID: <809@quintus.UUCP> Date: 5 Dec 88 06:06:54 GMT References: <791@quintus.UUCP> <3069@ttrdc.UUCP> Sender: news@quintus.UUCP Reply-To: ok@quintus.UUCP (Richard A. O'Keefe) Organization: Quintus Computer Systems, Inc. Lines: 46 In article <3069@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: >In article <791@quintus.UUCP>, ok@quintus writes: >> I offer the following F77 program for your interest and amusement. >> On VAXen it prints "BROKEN". On Sun3s it prints "BROKEN". On a >> Sequent (BSD UNIX, 386/387 processor, own Fortran) it prints "OK". > >Is the bug machine-specific? It also prints "BROKEN" on VMS FORTRAN 4.2-102, >which surprised me since DEC's VMS FORTRAN is generally an excellent compiler. Although I had the program print "BROKEN" under certain circumstances, I meant by that only that the behaviour violated ordinary mathematical intuition. I don't know what the Fortran standard says about this, but I suspect that technically it is *not* a bug. Here it is again: X = 1000000002 Y = 1000000001.0D0 Z = 1000000000.0E0 IF (X.GT.Y .AND. Y.GT.Z .AND..NOT. X.GT.Z) STOP 'BROKEN' where X: integer, Y: double precision, Z: real. What's going on here? Well, the comparison of X with Y is likely to be done by converting X to the same kind of float as Y, namely double precision. Similarly, the comparison of Y with Z is likely to be done by converting Z to the same kind of float as Y, namely double precision. In neither case was any information lost from either operand. But the comparison of X with Z is done by converting X to the same kind of float as Z, namely SINGLE precision, and in this case enough of X's precision is lost for FLOAT(X) to compare equal to Z. The key is that precision(DOUBLE PRECISION) >= precision(INTEGER) > precision(REAL). Now on a 68881 or 83087, the floating-point co-processor is carrying around 80 bits per FP register anyway, so the chances are that the comparison is being done in double or better precision. The point is that if you don't want to be surprised by non-transitivity of comparison, when two operands of different types are met, they should both be converted to something which has sufficient range and sufficient precision to represent both operands without loss of information. With the usual Fortran (and Common Lisp!) rules, it is very easy to make up examples like IF (I.EQ.Y .AND. Y.EQ.K .AND. I.GT.K) STOP 'BROKEN' I did say that this was offered for interest and amusement, and if anyone took it as a claim that Sun's or anyone else's compilers violate anything but the Law of Least Surprise, I apologise.