Fortran Format?

Q

Qubert

OK, I have an algorithm that I created to format a series of numbers
for a column centric FORTRAN routine to use. I don't like what I have
created, although it works, so I would like to ask if anyone here has
a more cleaver way.

Problem: I have a series of numbers that need to be formated as a
FORTRAN program would. That is, FORTRAN cares more about columns than
numbers so I need to fake the output of Ruby to make it look "decimal
justified".

Example, a series of numbers:
3.15, 122.5, 303.123, 55.0
Input for C or Ruby (the space means a new number):
3.15 122.5
303.123 55.0
Input needed for FORTRAN with format (f7.3,f5.1):
3.150122.5
303.123 55.0

My Ruby hack to put spaces at the begining if necessary:
def ff(num,len1,len2)
x = num.to_s.split(".")
numstring = ""
x[0].size.upto(len1 - 1) {|b| numstring << ' '}
numstring << x[0] << "."
numstring << x[1][0..len2]
end

code...
bla ...
printf("%s %s\n", ff(3.150,3,3),ff(122.5,3,1)
printf("%s %s\n", ff(303.123,3,3),ff(55.0,3,1)

I know that this needs improvement so your help would be appreciated.
I have to interface with these types of FORTRAN programs a lot, thus
far I have avoided this.
Thanks,
Chris
 
H

Hal Fulton

Qubert said:
printf("%s %s\n", ff(3.150,3,3),ff(122.5,3,1)
printf("%s %s\n", ff(303.123,3,3),ff(55.0,3,1)

More like

printf("%7.3f%5.1f\n",3.15,122.5)


Hal
 
M

Mark Sparshatt

Qubert said:
OK, I have an algorithm that I created to format a series of numbers
for a column centric FORTRAN routine to use. I don't like what I have
created, although it works, so I would like to ask if anyone here has
a more cleaver way.

Problem: I have a series of numbers that need to be formated as a
FORTRAN program would. That is, FORTRAN cares more about columns than
numbers so I need to fake the output of Ruby to make it look "decimal
justified".

Example, a series of numbers:
3.15, 122.5, 303.123, 55.0
Input for C or Ruby (the space means a new number):
3.15 122.5
303.123 55.0
Input needed for FORTRAN with format (f7.3,f5.1):
3.150122.5
303.123 55.0

My Ruby hack to put spaces at the begining if necessary:
def ff(num,len1,len2)
x = num.to_s.split(".")
numstring = ""
x[0].size.upto(len1 - 1) {|b| numstring << ' '}
numstring << x[0] << "."
numstring << x[1][0..len2]
end

code...
bla ...
printf("%s %s\n", ff(3.150,3,3),ff(122.5,3,1)
printf("%s %s\n", ff(303.123,3,3),ff(55.0,3,1)
A better way would be to be to use the sprintf method (documented on
page 427 of the pickaxe) to format the string.

The following code does what you want

def ff(num, len1, len2)
sprintf("%#{len1 + len2 + 1}.#{len2}f", num)
end

printf("%s %s\n", ff(3.150,3,3),ff(122.5,3,1))
printf("%s %s\n", ff(303.123,3,3),ff(55.0,3,1))

I know that this needs improvement so your help would be appreciated.
I have to interface with these types of FORTRAN programs a lot, thus
far I have avoided this.
HTH
 
G

gabriele renzi

il 19 May 2004 14:40:13 -0700, (e-mail address removed) (Qubert) ha
scritto::
I know that this needs improvement so your help would be appreciated.
I have to interface with these types of FORTRAN programs a lot, thus
far I have avoided this.

maybe:
"%7.3f%5.1f\n" % [3.15,122.5]
=> " 3.150122.5\n"
 
A

Ara.T.Howard

Qubert said:
OK, I have an algorithm that I created to format a series of numbers
for a column centric FORTRAN routine to use. I don't like what I have
created, although it works, so I would like to ask if anyone here has
a more cleaver way.

Problem: I have a series of numbers that need to be formated as a
FORTRAN program would. That is, FORTRAN cares more about columns than
numbers so I need to fake the output of Ruby to make it look "decimal
justified".

Example, a series of numbers:
3.15, 122.5, 303.123, 55.0
Input for C or Ruby (the space means a new number):
3.15 122.5
303.123 55.0
Input needed for FORTRAN with format (f7.3,f5.1):
3.150122.5
303.123 55.0

My Ruby hack to put spaces at the begining if necessary:
def ff(num,len1,len2)
x = num.to_s.split(".")
numstring = ""
x[0].size.upto(len1 - 1) {|b| numstring << ' '}
numstring << x[0] << "."
numstring << x[1][0..len2]
end

code...
bla ...
printf("%s %s\n", ff(3.150,3,3),ff(122.5,3,1)
printf("%s %s\n", ff(303.123,3,3),ff(55.0,3,1)
A better way would be to be to use the sprintf method (documented on
page 427 of the pickaxe) to format the string.

The following code does what you want

def ff(num, len1, len2)
sprintf("%#{len1 + len2 + 1}.#{len2}f", num)
end

printf("%s %s\n", ff(3.150,3,3),ff(122.5,3,1))
printf("%s %s\n", ff(303.123,3,3),ff(55.0,3,1))


this will not work on 'too wide' numbers as printf never truncates, eg:

~ > cat a.rb
def ff(num, len1, len2); sprintf("%#{len1 + len2 + 1}.#{len2}f", num); end

puts(ff(12345.12345, 3, 3))

~ > ruby a.rb
12345.123

the fortan format specifier says that the output/input will be EXACTLY as
wide as specified - not expanded. in otherwords it WILL truncate on output
and respect columns (not whitespace like scanf) in input. it's really a
terrible thing ;-(. in any case, something like this may work:


~ > cat b.rb
def ff num, len1, len2
(sprintf "%#{ len1 }.#{ len2 }f", num)[0...len1]
end
puts(ff(12345.12345, 3, 3))
puts "#{ ff 3.15, 7, 3 }#{ ff 122.5, 5, 1 }"
puts "#{ ff 303.123, 7, 3 }#{ ff 55.0, 5, 1 }"

~ > ruby b.rb
123
3.150122.5
303.123 55.0

but my fortran is rusty... i forget if the decimal bit is required? if so this
won't work since it may eject the mantissa... so, truncation is needed to
enforce field width but i'm not positive this is the correct method of
truncation... hopefully, since you are working with fortran actively, you will
know the answer to this ;-)


cheers.

-a
--
===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| URL :: http://www.ngdc.noaa.gov/stp/
| "640K ought to be enough for anybody." - Bill Gates, 1981
===============================================================================
 
R

Robert Klemme

Mark Sparshatt said:
Qubert said:
OK, I have an algorithm that I created to format a series of numbers
for a column centric FORTRAN routine to use. I don't like what I have
created, although it works, so I would like to ask if anyone here has
a more cleaver way.

Problem: I have a series of numbers that need to be formated as a
FORTRAN program would. That is, FORTRAN cares more about columns than
numbers so I need to fake the output of Ruby to make it look "decimal
justified".

Example, a series of numbers:
3.15, 122.5, 303.123, 55.0
Input for C or Ruby (the space means a new number):
3.15 122.5
303.123 55.0
Input needed for FORTRAN with format (f7.3,f5.1):
3.150122.5
303.123 55.0

My Ruby hack to put spaces at the begining if necessary:
def ff(num,len1,len2)
x = num.to_s.split(".")
numstring = ""
x[0].size.upto(len1 - 1) {|b| numstring << ' '}
numstring << x[0] << "."
numstring << x[1][0..len2]
end

code...
bla ...
printf("%s %s\n", ff(3.150,3,3),ff(122.5,3,1)
printf("%s %s\n", ff(303.123,3,3),ff(55.0,3,1)
A better way would be to be to use the sprintf method (documented on
page 427 of the pickaxe) to format the string.

The following code does what you want

def ff(num, len1, len2)
sprintf("%#{len1 + len2 + 1}.#{len2}f", num)
end

sprintf can already handle widths as arguments:

sprintf( "%*.*f", len1 + len2, len2, num )
printf("%s %s\n", ff(3.150,3,3),ff(122.5,3,1))
printf("%s %s\n", ff(303.123,3,3),ff(55.0,3,1))
3.150 122.5

:)

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,146
Messages
2,570,832
Members
47,374
Latest member
anuragag27

Latest Threads

Top