GL4@psuvm.psu.edu (06/04/90)
(I hope this isn't a repost -- I think I screwed up the first time) A user brought the following program to my attention, and I am unable to explain the output: --------------------------------------------- x=1.11 fs=10.0 write(*,32) x,fs 32 format(1pe13.3,f10.1) write(*,*) fs end --------------------------------------------- output: 1.111E+00 100.0 10.00000 --------------------------------------------- Does anyone know why the value of "fs" is multiplied by a factor of ten? I've tried this on a Sun-3, a Gould 9005 running UTX/32 2.1A, and an IBM mainframe, and gotten the same results. If I change the number in front of "pe" to a 2, "fs" is multiplied by a factor of 10**2, and so on. Any clarification would be greatly appeciated (even of the type, "This is standard Fortran behaviour, you lamebrain. RFTM"). Garth Longdon. gl4@psuvm.bitnet longdon@itd.nrl.navy.mil
calvin@dinkum.sgi.com (Calvin H. Vu) (06/05/90)
In article <90155.122858GL4@psuvm.psu.edu> GL4@psuvm.psu.edu writes: >--------------------------------------------- > x=1.11 > fs=10.0 > write(*,32) x,fs >32 format(1pe13.3,f10.1) > write(*,*) fs > end >--------------------------------------------- >output: > 1.111E+00 100.0 > 10.00000 >--------------------------------------------- > Does anyone know why the value of "fs" is multiplied by a factor of > ten? I've tried this on a Sun-3, a Gould 9005 running UTX/32 2.1A, > and an IBM mainframe, and gotten the same results. The P Editing causes every real number following it (until another P editing if any) to be multiplied by 10**k where k is called the scale factor and is the number in front of the P. A less confusing way to write this is: 32 format(1p,e13.3,f10.1) Without the scale factor specified, i.e. if the format had been: 32 format(e13.3,f10.1) the result would have been: 0.111E+01 10.0 10.00000 If you note the difference between the two results you can figure out the effects of the P edit descriptor. I'm a little lazy to type all the details so maybe you do need to RTFM :-). -------------------------------------------------------------------------- Calvin H. Vu | "We are each of us angels with Silicon Graphics Computer Systems | only one wing. And we can only calvin@sgi.com (415) 962-3679 | fly embracing each other."
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (06/05/90)
In article <90155.122858GL4@psuvm.psu.edu>, GL4@psuvm.psu.edu writes:
* x=1.11
* fs=10.0
* write(*,32) x,fs
* 32 format(1pe13.3,f10.1)
* ---------------------------------------------
* 1.111E+00 100.0
^^^^^ I hope this was really 1.11
"p" isn't a modifier on a single format, but a formatting command
in its own right, whose effect persists within the same format until
you explicitly reset it. Blank and sign handling are similar.
That's the way it's supposed to be.
--
"A 7th class of programs, correct in every way, is believed to exist by a
few computer scientists. However, no example could be found to include here."
maine@elxsi.dfrf.nasa.gov (Richard Maine) (06/05/90)
On 4 Jun 90 16:28:58 GMT, GL4@psuvm.psu.edu (Garth Longdon) said: Garth> A user brought the following program to my attention, and I am Garth> unable to explain the output: Garth> ... Garth> 32 format(1pe13.3,f10.1) Garth> ... Garth> ...[questions about the effects of the P scale factor in formats].. Garth> Any clarification would be greatly appeciated (even of the type, "This Garth> is standard Fortran behaviour, you lamebrain. RFTM"). Ok, I'll go with "This is standard Fortran behavior", but I can't agree with the "lamebrain" part. Though it is standard, it is certainly subtle and confusing. I've had quite competent programmers come to me after spending many hours trying to "debug" programs whose only problem was in the output format statement. (They were trying to figure out how the values got to be a factor of 10 off, not realizing that this was an artifact of the format). And I'll try to elaborate a little on the FM. You are seeing the combined effects of two confusing "features". The first feature, as pointed out by some other follow-ups, is that the P scale factor continues its effect throughout the format statement, even though it is placed next to the e13.3 in a manner that "looks like" it applies only to the e13.3 part. To make the !p apply only to the e13.3, you could do something like format(1p,e13.3,0p,f10.1) The second feature is the strange effect of the P scale factor on F format descriptors. I'd explain the effect by saying that the P scale factor does the same thing to the mantissa of E and F format items; it multiplies them by the appropriate power of ten. On E formats, it then compensates by lowering the exponent value. On F formats, there is no exponent, so the number is just left off by some factor of 10. I think this behavior is "wrong". I have never seen anywhere that such behavior was desirable, and I've seen plenty of users confused by it. Sure, you could invent some situation where this feature could be used, but I'm dubious that those rare cases justify the confusions caused elsewhere. Regardless of my opinions about this feature, it is standard. Oh yes, if I recall, the effects on input are equally confusing. While I'm on the subject of P scale factors, let me point out another "feature" that I think is a bug in the standard (but a bug that all the compiler vendors seem to strictly follow). I mentioned this bug in my official comments on the Fortran 90 standard, though I didn't really expect the ANSI committee to make any changes based on my comment, this bug having by now achieved the status of standard practice. If you use the P scale factor with G format descriptors, it does strange things to the number of significant digits for no ascertainable reason. For instance, without a scale factor, the format descriptor G10.4 always gives 4 significant digits. This is the most significance you can get in a 10-character field with E or G (or D) formats for arbitrary values (well, anyway if the exponent is limitted between -99 and +99). It happens that this precision is just barely adequate for some of my applications. You would not think (anyway, I wouldn't) that the scale factor would have anything to do with the number of significant digits. Indeed 1PG10.4 still has 4 significant digits when the value is in the range that gives an "F type" output. However, for large or small values such that an "E type" output results, 1PG10.4 gives 5 significant digits (and thus does not fit in the field of 10 for negative values). The same 5 significant digits result for all P values except 0; that is, 2PG10.4 and 3PG10.4 also give 5 significant digits (should anyone ever want them, negative scale values still give 5 digits, though some of them are leading 0's and thus not technically "significant" by most definitions). Thus, if you want to use a scale factor with G format decsriptors, the most significance you can fit in a field of 10 is with 1PG10.3. This gives 4 significant digits in the E form, but only 3 in the F form. The 3 significant digits are insufficient for me, so I avoid using scale factors with G format, much as I generally prefer !p to the default 0P. I have never been able to figure out the rationale for this behavior. My best guess is that it is simply a "typo" in the standard and not what was intended. Perhaps one of the committee members that frequent this group can correct this guess. Regardless of the intent, it IS in the standard, and compilers DO implement it. -- Richard Maine maine@elxsi.dfrf.nasa.gov [130.134.64.6]
GL4@psuvm.psu.edu (06/07/90)
Thanks to everyone who e-mailed me about the problem I was having with the "p" format specifier. As everyone noted, this really *is* standard (although very strange) FORTRAN behavior. I'd be curious to know if anyone can think of a sitution where you'd actually *want* the magnitude of the output to be changed like that. Garth Longdon.
jeffe@eniac.seas.upenn.edu (George J. Jefferson) (06/07/90)
>I'd be curious to know if anyone can think of a sitution where you'd actually >*want* the magnitude of the output to be changed like that when writing labels for a plot axis you can 'scale' all of the values and then indicate the 'scale factor' just once However, uses like this are so rare that the programer could just as well do it 'by hand' George Jefferson jeffe@eniac.seas.upenn.edu george@sol1.lrsm.upenn.edu
buckland@cheddar.ucs.ubc.ca (Tony Buckland) (06/08/90)
In article <90158.091706GL4@psuvm.psu.edu> GL4@psuvm.psu.edu writes: > >Thanks to everyone who e-mailed me about the problem I was having with the >"p" format specifier. As everyone noted, this really *is* standard (although >very strange) FORTRAN behavior. > >I'd be curious to know if anyone can think of a sitution where you'd actually >*want* the magnitude of the output to be changed like that. One use is in scaled currency applications, where you have internal cents or centicents and want to print dollars or cents without the bother of dividing everything by a hundred first. I could see extending this to scientific calculations where nanometers are printed as Angstrom units, etc. Returning to the currency case, you can see the advantage of being able to print an entire financial report with hundreds of variables, scaling everything with just one itty-bitty "P" at the beginning of the FORMAT.
jlg@lambda.UUCP (Jim Giles) (06/08/90)
From article <90158.091706GL4@psuvm.psu.edu>, by GL4@psuvm.psu.edu: > [...] > I'd be curious to know if anyone can think of a sitution where you'd actually > *want* the magnitude of the output to be changed like that. Consider a code in which you know that a given value is stored internally in meters. With the Fortran rules, you can write: Write(*,'('' Distance is '',6pf10.6,'' microns'')') x Later, you can just change the format to get: write(*,'('' Distance is '',3pf10.6,'' millimeters'')') x Admittedly, this is not a really particularly useful or common feature. I would also prefer that P not effect F formats and P should only effect one format specifier not all until the next P. However, such a change is unlikely because of backward compatibility. J. Giles
seymour@milton.acs.washington.edu (Richard Seymour) (06/08/90)
there's also the case of using Exponent notation (E-format). in standard fortran (ansi x3.9-1978 page 13-11) the ONLY way to get other than a single zero to appear to the left of the decimal point is via the P scale factor. E12.3 gives 0.270e+02 as output 1PE12.3 gives 2.701e+01 as output 2PE12.3 gives 27.012e+00 as output (i believe) there is NO other way (without building strings of integers) to get other than a single zero before that decimal point. (the same argument applies if you want leading zeroes to the RIGHT of the decimal point: -1PE12.3 gives 0.027e+04 ) --dick
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (06/08/90)
In article <8159@ubc-cs.UUCP>, buckland@cheddar.ucs.ubc.ca (Tony Buckland) writes: > In article <90158.091706GL4@psuvm.psu.edu> GL4@psuvm.psu.edu writes: > >Thanks to everyone who e-mailed me about the problem I was having with the > >"p" format specifier. As everyone noted, this really *is* standard (although > >very strange) FORTRAN behavior. > >I'd be curious to know if anyone can think of a sitution where you'd actually > >*want* the magnitude of the output to be changed like that. Several people have suggested why you would want P at all, though no-one as yet has pointed out that decimal scaling can be done by the formatting routines without _any_ extra roundoff error. As to why you would want it to be sticky, consider two facts: (a) you want pe, pf, pg, so it looks as though it might be simpler for the "p" part to be a separate formatting command (b) but you also want p10e and the like, and it's simplest to explain (and implement!) if p just sets a global variable. Another possibility would have been for everything that uses the 'p' flag to reset it to its default value, but then you'd have to write 10(p,e) rather than p,10e and unfortunately that might not interact with Fortran's rules about the last set of parens in a format just the way you would want. So my surmise is that the expectation was that if you wanted scaling you were probably printing out a table and wanted everything scaled the same way, and that if you didn't want everything scaled the same way it would be clearer if everything in the format had its own scale. A rule of thumb for keeping things straight, then, is that if you use P in a format at all, you should either put P first in the format (so you _know_ when it is set and that it applies to everything) or give each relevant item its own P -- "A 7th class of programs, correct in every way, is believed to exist by a few computer scientists. However, no example could be found to include here."