On Thu, 20 May 2004, Mark Sparshatt wrote:

> Qubert wrote:
> 
> >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
===============================================================================