|
|
 |
 |
 |
 |
Fortran Programming Language
|
 |
 |
 |
 |
 |
 |
 |
 |
print formatting of double precision variables
What is the best way to print an unknown value that could be just about anything in the double precision range ? I usually use G12.5 or G14.7 if I have the room. However, these do not give consistent results and they do not display very many digits. I am just about ready to give up and write a custom character*12 function that will always give me the maximum amount of digits. Please note that I am still using a F77 compiler (Open Watcom F77). Thanks, Lynn McGuire
Lynn McGuire wrote: > What is the best way to print an unknown value that could be just about > anything in the double precision range ? I usually use G12.5 > or G14.7 if I have the room. However, these do not give consistent > results and they do not display very many digits.
IEEE double provides about 16.2 digits. To allow for rounding I would probably try to print 15, maybe only 14. To get one extra digit for a given width, and agree with scientific tradition, use the 1P scale factor. So I choose 1PG22.14. That is, one digit before and 14 after the decimal point. Room for a sign, leading digits, decimal point, exponent sign, and then either E and two digits or three digits for exponent. That includes one leading blank for space between fields, if you don't need that 1PG21.14 should work. -- glen
>What is the best way to print an unknown value that could be just >about anything in the double precision range ? I usually use G12.5 >or G14.7 if I have the room.
In that situation I generally use something like G23.17 -- x86 doubles can have up to 16 decimal digits of precision, IIRC temp-real (80 bit x86 float) can handle a full 18 digits.
Lynn McGuire <nos @nospam.com> wrote: > What is the best way to print an unknown value that could be just > about anything in the double precision range ? I usually use G12.5 > or G14.7 if I have the room. However, these do not give consistent > results and they do not display very many digits. > I am just about ready to give up and write a custom character*12 > function that will always give me the maximum amount of digits. > Please note that I am still using a F77 compiler (Open Watcom F77).
The f77 bit hurts. Otherwise, the ES format of F90 is nice. You haven't said a lot about what your criteria are. Just using a nice big field is easy and trivial. I assume from context that you are trying to maximize the number of significant digits you can get in a field of modest width. People have discussed that general issue here not too awfully long ago. There are some definite tradeoffs in conciseness versus clarity; I can't answer those for you. For example, is it acceptable to omit the exponent letter as in 1.234-5 on the theory that this is unambiguous if you know that the - can't be subtraction in context? Anyway, although details vary, you pretty much have to do your custom function (or borrow one from someone else) if you want to do a very good job of maximizing this. The standard doesn't have anything very good in that regard. I think I recall that you can get by with E12.6 or equivalent scalings up or down, with the number of guaranteed significant digits 6 less than the field width. Actually, the case I most recall was E10.4, trying to squeeze a barely acceptable (to my app) 4 significant digits into a field of 10 columns, back in punched card days. You might think that E10.3 (or E12.5) was the best case, but the compiler is required to drop optional characters if that's what it takes to fit in a field; I'm pretty sure I recall that made E10.4 work. You can do a lot better than the width-6 significant digits in most cases if you do a custom function. Note that using 1P with G looses a significant digit. I went around on this with Glenn some time ago. I'm not having the argument again about whether it makes sense, etc. (I still think it was just plain an off-by-one typo in the standard, but I'm not arguing that any more). Regardless of the reason, the fact is that you can't guarantee as many significant digits in a give field width with 1PG as you can without the 1P. If you do a custom function, be wary of the recently discussed prohibition against recursive I/O. A function to do something like this is one example of where recursive I/O to an internal file is useful (and there's one more reference to that subject for Bob's count. :-)). You are really likely to want to use internal I/O in your function. That probably means you'll have to always do things like (ignore my non-f77 names) temp_char_var = your_function(whatever) write (lun,...) ..., temp_char_var, ... instead of write (lun,...) ..., your_function(whatever), ... Also, since you are stuck with f77, recall that list-directed internal I/O isn't allowed in standard f77. -- Richard Maine | Good judgement comes from experience; email: last name at domain . net | experience comes from bad judgement. domain: summertriangle | -- Mark Twain
> You haven't said a lot about what your criteria are. Just using a nice > big field is easy and trivial. I assume from context that you are trying > to maximize the number of significant digits you can get in a field of > modest width.
Yup, you got it. I would much rather that 1.23456e7 displays as 1234 > You can do a lot better than the width-6 significant digits in most > cases if you do a custom function.
That is what I figured. > If you do a custom function, be wary of the recently discussed > prohibition against recursive I/O. A function to do something like this > is one example of where recursive I/O to an internal file is useful (and > there's one more reference to that subject for Bob's count. :-)). You > are really likely to want to use internal I/O in your function. That > probably means you'll have to always do things like (ignore my non-f77 > names) > temp_char_var = your_function(whatever) > write (lun,...) ..., temp_char_var, ... > instead of > write (lun,...) ..., your_function(whatever), ...
Open Watcom f77 has many, many of the f90 extensions, 32 character names being one of them (thank goodness !). You mean I can't do something like: write (lun,111) (asString12 (x (i)), i = 1,6) 111 format (1x, (1x, a12)) > Also, since you are stuck with f77, recall that list-directed internal > I/O isn't allowed in standard f77.
What is list directed internal I/O ? Thanks, Lynn
> Yup, you got it. I would much rather that 1.23456e7 displays as 1234
Sigh. Fingers didnt read my brain correctly again. I meant: I would much rather that 1.23456e7 displays as 12345600.0. Thanks, Lynn
Lynn McGuire <nos @nospam.com> wrote: I wrote: > > If you do a custom function, be wary of the recently discussed > > prohibition against recursive I/O. > You mean I can't do something like: > write (lun,111) (asString12 (x (i)), i = 1,6) > 111 format (1x, (1x, a12))
That's corrrect. You cannot do that if asString does any I/O itself. That's *EXACTLY* what the restriction against recursive I/O is about. You are ok if asString does no I/O, but that's a major limitation for an application like this. Its a lot easier to use internal I/O to take advantage of the parts that Fortran formatting can already do for you rather than having to redo everything from scratch. > > Also, since you are stuck with f77, recall that list-directed internal > > I/O isn't allowed in standard f77. > What is list directed internal I/O ?
You know what internal I/O is, right? I hope so if you want to do a job like this. That's I/O to a character variable instead of a file. Basically, that's a way to use the Fortran formatting engine without actually having to involve a physical external file. And you know what list-directed I/O is, right? That's what you get using an * as the format. Some people call it something like free form or some such thing, which is ok. Other people incorrectly refer to it as unformatted, which is not so ok, since unformatted means something completely different (and directly contradictory) in Fortran. List-directed internal I/O is I/O that is both list-directed and internal, as in write(char_variable,*) whatever That's not legal in f77, but is in f90. -- Richard Maine | Good judgement comes from experience; email: last name at domain . net | experience comes from bad judgement. domain: summertriangle | -- Mark Twain
Richard Maine wrote: > Lynn McGuire <nos @nospam.com> wrote: (snip) > Anyway, although details vary, you pretty much have to do your custom > function (or borrow one from someone else) if you want to do a very good > job of maximizing this. The standard doesn't have anything very good in > that regard. I think I recall that you can get by with E12.6 or > equivalent scalings up or down, with the number of guaranteed > significant digits 6 less than the field width. Actually, the case I > most recall was E10.4, trying to squeeze a barely acceptable (to my app) > 4 significant digits into a field of 10 columns, back in punched card > days. You might think that E10.3 (or E12.5) was the best case, but the > compiler is required to drop optional characters if that's what it takes > to fit in a field; I'm pretty sure I recall that made E10.4 work.
Trying it out, it seems that E12.6 (and presumably E10.4) fine, though with no leading blanks, other than where the sign goes. Running it in gfortran, E11.6 works for positive numbers, but *********** for negative numbers and will leave no space between the last digit of the previous field, or the first digit of the next. > Note that using 1P with G looses a significant digit. I went around on > this with Glenn some time ago. I'm not having the argument again about > whether it makes sense, etc. (I still think it was just plain an > off-by-one typo in the standard, but I'm not arguing that any more). > Regardless of the reason, the fact is that you can't guarantee as many > significant digits in a give field width with 1PG as you can without the > 1P.
Yes, I don't want to get into an argument either. I just tried 1PG21.14 and I can see what it does (at least in one implementation). You get one more digit in E form, as is usual for 1P. As the standard says, there is no effect in non-E form, even though there is plenty of space for another digit. It does seem like a mistake in the standard. -- glen
"Lynn McGuire" <nos @nospam.com> wrote in message news:461bb59d$0$17205$39cecf19@news.twtelecom.net... > What is the best way to print an unknown value that could be just > about anything in the double precision range ? I usually use G12.5 > or G14.7 if I have the room. However, these do not give consistent > results and they do not display very many digits. > I am just about ready to give up and write a custom character*12 > function that will always give me the maximum amount of digits. > Please note that I am still using a F77 compiler (Open Watcom F77). > Thanks, > Lynn McGuire
...You could use my code. I posted it here a few weeks ago. See http://groups.google.com/group/comp.lang.fortran/browse_thread/thread... 126af71895/e54cc49eed61b1bd?lnk=gst&q=rcompact+munges&rnum=1&hl=en#e54cc49e e d61b1bd -- Qolin Email: my qname at domain Domain: qomputing dot demon dot co dot uk
"Colin Watters" <qolin.see_signat @nowhere.co.uk> wrote in message news:evm5tn$p3q$1$8300dec7@news.demon.co.uk...
> "Lynn McGuire" <nos@nospam.com> wrote in message > news:461bb59d$0$17205$39cecf19@news.twtelecom.net... >> What is the best way to print an unknown value that could be just >> about anything in the double precision range ? I usually use G12.5 >> or G14.7 if I have the room. However, these do not give consistent >> results and they do not display very many digits. >> I am just about ready to give up and write a custom character*12 >> function that will always give me the maximum amount of digits. >> Please note that I am still using a F77 compiler (Open Watcom F77). >> Thanks, >> Lynn McGuire > ...You could use my code. I posted it here a few weeks ago. See > http://groups.google.com/group/comp.lang.fortran/browse_thread/thread... > 126af71895/e54cc49eed61b1bd?lnk=gst&q=rcompact+munges&rnum=1&hl=en#e54cc49e e > d61b1bd
That makes for a long url. I'm curious whether this works: http://tinyurl.com/2y2cq9 -- ww
"Wade Ward" <inva @invalid.net> wrote in message news:ZJmdnZ1iZavrO4PbnZ2dnUVZ_g-dnZ2d@comcast.com...
> "Colin Watters" <qolin.see_signat@nowhere.co.uk> wrote in message > news:evm5tn$p3q$1$8300dec7@news.demon.co.uk... > > "Lynn McGuire" <nos@nospam.com> wrote in message > > news:461bb59d$0$17205$39cecf19@news.twtelecom.net... > >> What is the best way to print an unknown value that could be just > >> about anything in the double precision range ? I usually use G12.5 > >> or G14.7 if I have the room. However, these do not give consistent > >> results and they do not display very many digits. > >> I am just about ready to give up and write a custom character*12 > >> function that will always give me the maximum amount of digits. > >> Please note that I am still using a F77 compiler (Open Watcom F77). > >> Thanks, > >> Lynn McGuire > > ...You could use my code. I posted it here a few weeks ago. See
http://groups.google.com/group/comp.lang.fortran/browse_thread/thread...
126af71895/e54cc49eed61b1bd?lnk=gst&q=rcompact+munges&rnum=1&hl=en#e54cc49e e yup! -- Qolin Email: my qname at domain Domain: qomputing dot demon dot co dot uk
>> What is the best way to print an unknown value that could be just >> about anything in the double precision range ? I usually use G12.5 >> or G14.7 if I have the room. However, these do not give consistent >> results and they do not display very many digits. > ...You could use my code. I posted it here a few weeks ago. See
http://groups.google.com/group/comp.lang.fortran/browse_thread/thread... Thanks ! I will take a detailed look at it. Lynn
|
 |
 |
 |
 |
|