From: "Ara.T.Howard" Date: 2004-05-20T07:53:50+09:00 Subject: Re: Fortran Format? 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 ===============================================================================