Home > Archive > Fortran > November 2005 > Some formatting problems
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Some formatting problems
|
|
| BornAgainFortraner 2005-11-23, 7:00 pm |
| Salutations Fortraners:
I am trying to do some cellular programming of insect spread. Several
years back I promptly converted the original fortran77 program to C
(not wanting to deal with an obsolete language). Only recently did I
discover the power and elegance of the new Fortran 95 (array processing
etc). Since I am not a systems programmer & don't write huge programs,
I thought I'd convert the C program back to fortran 95 (so as not to be
stymied by C's intricacies). Well, all went well except for some
formatting issues:
This coud be a naive question.
Is there any equivalent of %d and %.2f, %.0f formatting statements like
C IN FORTRAN?
The problem is that I may not know the correct formatting statement
like I4 or F8.3 beforehand - all I would know is that I want it to
print a decimal number or a real number rounded to 2 digits.
Guessing and having a huge format statement like F12.4 etc produces
ugly results in the output. My converted Fortran program ran for 7 days
and produced ***** in the output much to my dismay (if it had atleast
ignored the format and produced a unformatted write, it would have
saved me 7 days!!).
I know a workaround - use formatless write statements and use gawk |
Perl | Python to reformat it using C like format statements. But, I was
hoping that with all the great features introduced in Fortran 90
onwards, something as basic and useful as this would be present.
My review says not. Hope I am mistaken.
Pra
| |
| Dan Nagle 2005-11-23, 7:00 pm |
| Hello,
BornAgainFortraner wrote:
> Salutations Fortraners:
<snip>
> I know a workaround - use formatless write statements and use gawk |
> Perl | Python to reformat it using C like format statements. But, I was
> hoping that with all the great features introduced in Fortran 90
> onwards, something as basic and useful as this would be present.
>
> My review says not. Hope I am mistaken.
Try F0.2 or similar.
--
Cheers!
Dan Nagle
Purple Sage Computing Solutions, Inc.
| |
| Gordon Sande 2005-11-23, 7:00 pm |
| On 2005-11-23 11:28:12 -0400, "BornAgainFortraner" <apra @fs.fed.us> said:
> Salutations Fortraners:
> I am trying to do some cellular programming of insect spread. Several
> years back I promptly converted the original fortran77 program to C
> (not wanting to deal with an obsolete language). Only recently did I
> discover the power and elegance of the new Fortran 95 (array processing
> etc). Since I am not a systems programmer & don't write huge programs,
> I thought I'd convert the C program back to fortran 95 (so as not to be
> stymied by C's intricacies). Well, all went well except for some
> formatting issues:
> This coud be a naive question.
> Is there any equivalent of %d and %.2f, %.0f formatting statements like
> C IN FORTRAN?
> The problem is that I may not know the correct formatting statement
> like I4 or F8.3 beforehand - all I would know is that I want it to
> print a decimal number or a real number rounded to 2 digits.
> Guessing and having a huge format statement like F12.4 etc produces
> ugly results in the output. My converted Fortran program ran for 7 days
> and produced ***** in the output much to my dismay (if it had atleast
> ignored the format and produced a unformatted write, it would have
> saved me 7 days!!).
> I know a workaround - use formatless write statements and use gawk |
> Perl | Python to reformat it using C like format statements. But, I was
> hoping that with all the great features introduced in Fortran 90
> onwards, something as basic and useful as this would be present.
>
> My review says not. Hope I am mistaken.
>
> Pra
You will want to look up some features of F90/F95. In particular
the nonadvancing I/O (F90) and the "zero" width formats (F95).
Thus you may have
write ( 6, '(1x,"N = ",i0)', advance = "no" ) n
write ( 6, '(1x,"M = ",i0)', advance = "no" ) m
write ( 6, '("")' )
to produce
N = 127 M = 7
or whatever the values happen to be. The interesting features
are the use of character strings for formats with internal strings
by using the alternate string quotes carefully, the nonadvancing I/O
and the zero length string to finish things off. This style can be
shortened but it is easier to modify.
But since you never have to modify your programs the advice
on how to make things shorter and crytpic will be invaluable. ;-)
| |
| BornAgainFortraner 2005-11-23, 7:00 pm |
| Thanks so much for such a quick response. I should have guessed that!
However, the format of I0 and F0.2 are not implemented correctly in the
g95 and the gfortran compilers on Windows/Cygwin. g95 implements I0
correctly but not F0.2 while gfortran implements F0.2 and I0 correctly
but not the 1x with advance="no" as I have explained below.
Here is what happens with the foll. statements:
DATA arr / 1, 208, 3, 4, 0, 6, 79, 0, 9, 10000, 0, 1200 /
DATA rearr /23.4 245.9087 23.89 1.0009 109876.54678 1.89 29.89 16.0009
10986.54678 223.899 10.0009 10987698.54678 /
DO I=1,R
DO J=1,C
WRITE(*, '(F0.2,1X)', advance='no') rearr(I,J)
END DO
END DO
gfortran implements the F0.2 correctly but does NOT print a space
between
the numbers (ignores 1x)
g95 just prints blanks (does not implement F0.2 at all!!)
DO I=1,R
DO J=1,C
WRITE(*, FMT='(I0,1X)', ADVANCE='NO') arr(I,J)
END DO
WRITE(*,*)
END DO
gfortran prints numbers right, but again does not print space between
the numbers (ignores 1x).
g95 prints the numbers with spaces correctly.
Questions: Are F0.2, I0 etc standard features? Which compilers other
than gfortran and g95 can I trust (hopefully free)? Is it common to
have these kinds of compiler problems in Fortran?
Thanks,
Pra
| |
| Steven G. Kargl 2005-11-23, 7:00 pm |
| In article <1132766689.995115.10650@g44g2000cwa.googlegroups.com>,
"BornAgainFortraner" <apra @fs.fed.us> writes:
> Thanks so much for such a quick response. I should have guessed that!
> However, the format of I0 and F0.2 are not implemented correctly in the
> g95 and the gfortran compilers on Windows/Cygwin. g95 implements I0
> correctly but not F0.2 while gfortran implements F0.2 and I0 correctly
> but not the 1x with advance="no" as I have explained below.
> Here is what happens with the foll. statements:
>
> DATA arr / 1, 208, 3, 4, 0, 6, 79, 0, 9, 10000, 0, 1200 /
> DATA rearr /23.4 245.9087 23.89 1.0009 109876.54678 1.89 29.89 16.0009
> 10986.54678 223.899 10.0009 10987698.54678 /
> DO I=1,R
> DO J=1,C
> WRITE(*, '(F0.2,1X)', advance='no') rearr(I,J)
> END DO
> END DO
This code does not compile, so one can't test your assertation.
What version of gfortran are you using?
--
Steve
http://troutmask.apl.washington.edu/~kargl/
| |
| Steven G. Kargl 2005-11-23, 7:00 pm |
| In article <dm298a$jp3$1@gnus01.u.washington.edu>,
kargl@troutmask.apl.washington.edu (Steven G. Kargl) writes:
> In article <1132766689.995115.10650@g44g2000cwa.googlegroups.com>,
> "BornAgainFortraner" <apra @fs.fed.us> writes:
>
> This code does not compile, so one can't test your assertation.
> What version of gfortran are you using?
>
After making your code compilable, I find that gfortran does the
right thing. You need to upgrade to a newer binary.
sgk[225] gfc41 --version
GNU Fortran 95 (GCC) 4.1.0 20051115 (experimental)
troutmask:sgk[226] gfc4x --version
GNU Fortran 95 (GCC) 4.2.0 20051121 (experimental)
Steve
http://troutmask.apl.washington.edu/~kargl/
| |
|
|
BornAgainFortraner wrote:
> Thanks so much for such a quick response. I should have guessed that!
> However, the format of I0 and F0.2 are not implemented correctly in the
> g95 and the gfortran compilers on Windows/Cygwin. g95 implements I0
> correctly but not F0.2
I'm finding on both linux and cygwin the correct behavior with g95:
> cat > mytest.f90
real*8 a
data a / 1234.567 /
write(6,'(F0.2,1X,F0.2)') a,a
END
> g95 mytest.f90
> ./a.exe
1234.57 1234.57
on cygwin I'm using :
gcc version 4.0.2 (g95!) Nov 20 2005
Cheers,
Joost
| |
| BornAgainFortraner 2005-11-23, 7:00 pm |
| Hi,
> gfortran --version
GNU Fortran 95 (GCC) 4.1.0 20051015 (experimental)
Copyright (C) 2005 Free Software Foundation, Inc.
Here is a test program that ignores 1x
Program Test
IMPLICIT NONE
INTEGER I,J
REAL, DIMENSION(4,3):: rearr
DATA rearr / 23.4, 245.9087, 23.89, 1.0009, 109876.54678, 1.89, 29.89,
16.0009, 10986.54678, 223.899, 10.0009, 10987698.54678 /
DO I=1,4
DO J=1,3
WRITE(*, '(F0.2,1X)', advance='no') rearr(I,J)
END DO
WRITE(*,*)
END DO
End Program Test
Thanks much.
Pra
| |
| Steven G. Kargl 2005-11-23, 7:00 pm |
| In article <1132769746.721917.268710@g43g2000cwa.googlegroups.com>,
"BornAgainFortraner" <apra @fs.fed.us> writes:
> Hi,
> GNU Fortran 95 (GCC) 4.1.0 20051015 (experimental)
> Copyright (C) 2005 Free Software Foundation, Inc.
>
> Here is a test program that ignores 1x
>
Works for me on FreeBSD. This could be a target
specific problem with cygwin. Can you update to a
newer gfortran from the wiki and see if the problem
still exists? If the problem occurs in the newer
gfortran, please file a bug report at gcc.gnu.org.
--
Steve
http://troutmask.apl.washington.edu/~kargl/
| |
| BornAgainFortraner 2005-11-23, 7:00 pm |
| Hi, Looks like I need the latest compiler - but I don't find the
windows installer for a later version. The cygwin version seems to be
even older gfortran-Cygwin-4.1-20050623.
g95 seems to produce real slow code even with optimizations.
So for now it looks like I should be satisfied with this workaround:
WRITE(*, '(F0.2,A1)', advance='no') rearr(I,J), ' '
although it will start looking ugly with many variables.
Thanks much for all your help. The F0.2 and I0 were real discoveries
for me.
Pra
| |
| Dick Russell 2005-11-23, 7:00 pm |
| If the Lahey LF95 Language Reference is an accurate interpretation of
the language standard, then it may be a matter of interpreting what the
1X is supposed to accomplish:
"The nX edit descriptor tabs n characters right from the current
position. .... If the position is changed to beyond the length of the
current record, the next data transfer to or from the record causes the
insertion of blanks in the character positions not previously filled."
What may be happening is that in a single execution of the WRITE, the
1X tabs past the real string written but does not introduce a blank
character, because there is no subsequent data transfer by that WRITE.
The "length of the current record" would then remain at the end of the
real string written, so that the next execution of the WRITE starts
there. How "advance='no' affects this isn't clear to me.
I am curious as to why you write out the array elements one element per
WRITE, rather than with something like this:
WRITE(*, '(999(F0.2,1X))) ((rearr(I,J), J=1,3), I=1,4)
What do you want the output to look like? Perhaps we should be
addressing how to do the WRITEs and format strings to get what you
really want, rather than talking about the 1X and advance='no' issues.
RAR
BornAgainFortraner wrote:
> Hi,
> GNU Fortran 95 (GCC) 4.1.0 20051015 (experimental)
> Copyright (C) 2005 Free Software Foundation, Inc.
>
> Here is a test program that ignores 1x
.......
> DO I=1,4
> DO J=1,3
> WRITE(*, '(F0.2,1X)', advance='no') rearr(I,J)
> END DO
> WRITE(*,*)
> END DO
> End Program Test
| |
| Dick Russell 2005-11-23, 7:00 pm |
| If the Lahey LF95 Language Reference is an accurate interpretation of
the language standard, then it may be a matter of interpreting what the
1X is supposed to accomplish:
"The nX edit descriptor tabs n characters right from the current
position. .... If the position is changed to beyond the length of the
current record, the next data transfer to or from the record causes the
insertion of blanks in the character positions not previously filled."
What may be happening is that in a single execution of the WRITE, the
1X tabs past the real string written but does not introduce a blank
character, because there is no subsequent data transfer by that WRITE.
The "length of the current record" would then remain at the end of the
real string written, so that the next execution of the WRITE starts
there. How "advance='no' affects this isn't clear to me.
I am curious as to why you write out the array elements one element per
WRITE, rather than with something like this:
WRITE(*, '(999(F0.2,1X))) ((rearr(I,J), J=1,3), I=1,4)
What do you want the output to look like? Perhaps we should be
addressing how to do the WRITEs and format strings to get what you
really want, rather than talking about the 1X and advance='no' issues.
RAR
BornAgainFortraner wrote:
> Hi,
> GNU Fortran 95 (GCC) 4.1.0 20051015 (experimental)
> Copyright (C) 2005 Free Software Foundation, Inc.
>
> Here is a test program that ignores 1x
.......
> DO I=1,4
> DO J=1,3
> WRITE(*, '(F0.2,1X)', advance='no') rearr(I,J)
> END DO
> WRITE(*,*)
> END DO
> End Program Test
| |
| BornAgainFortraner 2005-11-23, 7:00 pm |
| Well, the reason I want it in that format is to simulate a GIS layer in
ArcInfo AsciiGrid format. Since I have previously written most of the
code in C and have rediscovered the power of the new Fortran for our
research project, I was going the c2f route - and therefore wondering
why such a simple implementation is becoming so problematic in Fortran.
My knowledge of C and Fortran is limited to our research demands and
don't normally maintain or produce code for others. I seem to get by
most of the time with shell scripts, gawk and Python - but when it
comes to doing some real intensive computational stuff involving
cellular grids, higher level languages are necessary. The power of the
new fortran is really great for people like me - I don't have to invest
too much time in learning - and also be able to do all the "array"
stuff. C is good if you continuously invest time doing C/C++
programming; if not, the new fortran seems to be lot better.
Thanks again for all your inputs.
Pra
| |
| John Harper 2005-11-23, 7:00 pm |
| In article <1132772254.687249.112360@z14g2000cwz.googlegroups.com>,
Dick Russell <richard.russell@shawgrp.com> wrote:
>If the Lahey LF95 Language Reference is an accurate interpretation of
>the language standard, then it may be a matter of interpreting what the
>1X is supposed to accomplish:
>
>"The nX edit descriptor tabs n characters right from the current
>position. .... If the position is changed to beyond the length of the
>current record, the next data transfer to or from the record causes the
>insertion of blanks in the character positions not previously filled."
>
....
>How "advance='no' affects this isn't clear to me.
But I think the whole problem is the interaction between 1X and
advance='no'.
The f95 standard uses different wording from Lahey, and I suspect it
was found to be ambuguous (my unskilled typing inadvertently produced
that word, which I rather like in this context) because the f2003
standard is different again.
f95 9.2.1.3.3
If no error condition occurred in a nonadvancing output statement, the
file position is not changed.
f95 10.6.1.2 The nX edit descriptor indicates that the transmission of
the next character to or from a record is to occur at the position n
characters forward from the current position.
f2003 9.2.3.1
This standard contains the record positioning ADVANCE= specifier in a
data transfer statement that provides the capability of maintaining a
position within the current record from one formatted data transfer
statement to the next data transfer statement. The value NO provides
this capability.
f2003 10.7.1
On output, a T, TL, TR, or X edit descriptor does not by itself cause
characters to be transmitted and therefore does not by itself affect
the length of the record. If characters are transmitted to positions at
or after the position specified by a T, TL, TR, or X edit descriptor,
positions skipped and not previously filled are filled with blanks. The
result is as if the entire record were initially filled with blanks.
Pity the poor compiler-writers trying to make sense of the f95 conflict
between "the file position is not changed" and "n characters forward
from the current position"! I'm therefore not surprised that the
following program gave different output with Sun f95 and g95, and I'm
not at all sure which conforms to the f95 standard.
The first sentence quoted from f2003 10.7.1 above makes me suspect that
the Sun f95 behaviour is what f2003 compilers will require. Am I right?
The program:
INTEGER:: arr(3,2),r=3, c=2, i,j
DATA arr /1, 208, 3, -4, 0, 6/
DO j=1,c ! to print in the same order as in the DATA statement
DO i=1,r
WRITE(*, FMT='(I0,1X)', ADVANCE='NO') arr(i,j)
END DO
WRITE(*,*)
END DO
!
DO j=1,c
DO i=1,r
WRITE(*, FMT='(1X,I0)', ADVANCE='NO') arr(i,j)
END DO
WRITE(*,*)
END DO
END
Sun f95 output:
12083
-406
1 208 3
-4 0 6
Sun g95 output:
1 208 3
-4 0 6
1 208 3
-4 0 6
So '(1X,I0)' seems unambiguous, but whether it's what the OP really
wanted is another matter:-)
John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington, New Zealand
e-mail john.harper@vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045
| |
| Joe Krahn 2005-11-23, 7:00 pm |
| BornAgainFortraner wrote:
> Thanks so much for such a quick response. I should have guessed that!
> However, the format of I0 and F0.2 are not implemented correctly in the
> g95 and the gfortran compilers on Windows/Cygwin. g95 implements I0
> correctly but not F0.2 while gfortran implements F0.2 and I0 correctly
> but not the 1x with advance="no" as I have explained below.
> Here is what happens with the foll. statements:
>
> DATA arr / 1, 208, 3, 4, 0, 6, 79, 0, 9, 10000, 0, 1200 /
> DATA rearr /23.4 245.9087 23.89 1.0009 109876.54678 1.89 29.89 16.0009
> 10986.54678 223.899 10.0009 10987698.54678 /
> DO I=1,R
> DO J=1,C
> WRITE(*, '(F0.2,1X)', advance='no') rearr(I,J)
> END DO
> END DO
>
> gfortran implements the F0.2 correctly but does NOT print a space
> between
> the numbers (ignores 1x)
....
Instead of '(F0.2,1X)', try using '(1X,F0.2)'. Just a guess at a
work-around.
Joe Krahn
| |
| Gib Bogle 2005-11-24, 9:56 pm |
| BornAgainFortraner wrote:
> Well, the reason I want it in that format is to simulate a GIS layer in
> ArcInfo AsciiGrid format.
I suspect that you didn't understand what Dick said. He isn't
questioning the format you want the output in, he's questioning the
means you are using to achieve it. The point is that while in C you
need an explicit loop to write many values on a line, in Fortran things
are much easier, with implicit looping in the write statement. A single
Fortran write as he suggested should be perfectly adequate for your needs.
| |
|
|
BornAgainFortraner wrote in message <1132759692.073691.61230@o13g2000cwo.googlegroups.com>...
>Salutations Fortraners:
>The problem is that I may not know the correct formatting statement
>like I4 or F8.3 beforehand - all I would know is that I want it to
>print a decimal number or a real number rounded to 2 digits.
>Guessing and having a huge format statement like F12.4 etc produces
>ugly results in the output.
There are the E format and the G format, which cater for a wide range
of values.
> My converted Fortran program ran for 7 days
>and produced ***** in the output much to my dismay (if it had atleast
>ignored the format and produced a unformatted write, it would have
>saved me 7 days!!).
When the magnitude of a value is not known in advance,
E format and G format can be of great help.
[others have suggested also zero-width specifiers; for reals these can
be helpful provided that the value is not wildly large.]
>Pra
| |
| Catherine Rees Lay 2005-11-29, 7:57 am |
| BornAgainFortraner wrote:
<snip>
> The problem is that I may not know the correct formatting statement
> like I4 or F8.3 beforehand - all I would know is that I want it to
> print a decimal number or a real number rounded to 2 digits.
> Guessing and having a huge format statement like F12.4 etc produces
> ugly results in the output.
<snip>
It sounds like you've got a solution to your problem - but I'll just add
for completeness since nobody else has mentioned it that a Fortran
format is just a string. So you can do something like
character fmt*8
real rnum
if (rnum.lt.100) then
fmt = '(F5.2)'
else
fmt = '(F12.2)'
endif
write (*,fmt) rnum
(yes, I know it's a crummy example, but just to illustrate that you can
use a format statement which you build at runtime depending on the
value(s) to be printed).
Catherine.
| |
| Gordon Sande 2005-11-29, 7:01 pm |
| On 2005-11-29 06:12:16 -0400, Catherine Rees Lay
<spamtrap@polyhedron.com> said:
> BornAgainFortraner wrote:
>
> <snip>
>
>
> <snip>
>
> It sounds like you've got a solution to your problem - but I'll just
> add for completeness since nobody else has mentioned it that a Fortran
> format is just a string. So you can do something like
>
> character fmt*8
> real rnum
>
> if (rnum.lt.100) then
> fmt = '(F5.2)'
> else
> fmt = '(F12.2)'
> endif
>
> write (*,fmt) rnum
>
> (yes, I know it's a crummy example, but just to illustrate that you can
> use a format statement which you build at runtime depending on the
> value(s) to be printed).
>
> Catherine.
Rather than assign format strings you could use nonadvancing
I/O and choose which write statements are to be executed.
Similar amount of decision making with diffeing requirements
on how the decisions are recorded and acted upon.
|
|
|
|
|