Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

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

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

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

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

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc