Path: utzoo!attcan!uunet!lll-winken!ames!ncar!tank!uxc!uxc.cso.uiuc.edu!uxg.cso.uiuc.edu!uxe.cso.uiuc.edu!hirchert From: hirchert@uxe.cso.uiuc.edu Newsgroups: comp.lang.fortran Subject: Re: CFT/CFT77 gotcha Message-ID: <50500099@uxe.cso.uiuc.edu> Date: 23 Jan 89 14:51:00 GMT References: <23252@beta.lanl.gov> Lines: 50 Nf-ID: #R:beta.lanl.gov:23252:uxe.cso.uiuc.edu:50500099:000:2251 Nf-From: uxe.cso.uiuc.edu!hirchert Jan 23 08:51:00 1989 dd@beta.lanl.gov writes >I came across an interesting non-bug in CFT77 today. A program >fragment: > a = 6.0 > b = 3.0 > i = a / b > >gave the result "2" in CFT on a X/MP-48 and "1" in CFT77 on the >same machine. >... >At least I didn't write the code! Now, is this a bug or a feature? The key property here is that CRAY computers have no divide instruction, only a way of computing reciprocals, so a/b is computed as a*(1.0/b). The method of computing reciprocals is such that if it is not exact, it is smaller than the true reciprocal. Thus 1.0/3.0 = .333...33 6.0*(1.0/3.0)=1.99...98 With either compiler, if you had written c=a/b i=c the result would have been 1 because REAL to INTEGER assignment is defined as truncating the fractional part of the number, no matter how close it is to the next number. In the original CFT compiler, they recognize the special case of a REAL division being assigned to an INTEGER and apply not NINT(), but "strong rounding". This consists of multiplying the result by 1.00...02 and then truncating. This extra fudge factor compensates for the extent to which the computed reciprocal might be lower than a true reciprocal and gives the expected answer in most cases. In developing CFT77, CRAY recognized that this extra multiply slowed down all divides in this kind of situation, not just those that were expected to be exact and that it could be confusing to get different results depending on whether or not you assigned the intermediate REAL quotient to a variable, so they chose not to do "strong rounding" in this case and instead issue a warning message. (Did you ignore this warning message, dd?) Incidentally, CRAY hardware also has no INTEGER divide instruction. In this case, both compilers convert to floating point, do the reciprocal approximation and multiple, and then apply "strong rounding" before converting back to INTEGER, since INTEGER arithmetic is expected to be exact. Bug or feature? I suppose you would have to say "feature", but really it is an example of the fact that you should not make assumptions about the properties of floating point arithmetic. Kurt W. Hirchert hirchert@ncsa.uiuc.edu National Center for Supercomputing Applications