[comp.lang.fortran] .GT. is not transitive

ok@quintus (12/02/88)

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".
I know why it fails on the machines where it fails and why it
works on the Sequent.  The numeric values are appropriate for
machines with 32-bit INTEGERs, 32-bit IEEE REALs, and 64-bit IEEE
DOUBLE PRECISIONs.

	INTEGER X
	DOUBLE PRECISION Y
	REAL Z

	X = 1000000002
	Y = 1000000001.0D0
	Z = 1000000000.0E0

	IF (X.GT.Y .AND. Y.GT.Z .AND..NOT. X.GT.Z) STOP 'BROKEN'
	STOP 'OK'

	END

ok@quintus.uucp (Richard A. O'Keefe) (12/02/88)

In article <791@quintus.UUCP> I wrote
>Sequent (BSD UNIX, 386/387 processor, own Fortran) it prints "OK".
				       ^^^
I meant >>Sequent's<< own "fortran", which is not based on the usual
UNIX "f77" compiler.  Sorry if anyone was misled.

gsh7w@astsun1.acc.virginia.edu (Greg Hennessy) (12/03/88)

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".  

It prints "OK" on my sun3/50 with f68881. No special flags except a
setenv FLOAT_OPTION "-f68881".



-Greg Hennessy, University of Virginia
 USPS Mail:     Astronomy Department, Charlottesville, VA 22903-2475 USA
 Internet:      gsh7w@virginia.edu  
 UUCP:		...!uunet!virginia!gsh7w

charlie@mica.stat.washington.edu (Charlie Geyer) (12/03/88)

In article <837@hudson.acc.virginia.edu> gsh7w@astsun1.acc.Virginia.EDU (Greg Hennessy) 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".  
>
>It prints "OK" on my sun3/50 with f68881. No special flags except a
>setenv FLOAT_OPTION "-f68881".

And prints "BROKEN" on a Sun 3/160 with fpa.

  pollux_40% f77 -o broken -ffpa broken.f
  pollux_41% broken
  STOP: BROKEN

levy@ttrdc.UUCP (Daniel R. Levy) (12/04/88)

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.
-- 
|------------Dan Levy------------|  THE OPINIONS EXPRESSED HEREIN ARE MINE ONLY
| Bell Labs Area 61 (R.I.P., TTY)|  AND ARE NOT TO BE IMPUTED TO AT&T.
|        Skokie, Illinois        | 
|-----Path:  att!ttbcad!levy-----|

ok@quintus.uucp (Richard A. O'Keefe) (12/05/88)

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.