[comp.lang.fortran] Left justify of integers.

quan@sol.surv.utas.edu.au (Stephen Quan) (05/31/91)

I'm having a slight, almost trivial problem, I cannot write
integers without them being right justified.

eg  write (*,*) 5

    gives

    ......5   (. are leading spaces)


Is there some format statement (i1.1 or something) that will
solve this problem?  I want a general solution, not just :

    write (*,'(i1)') 5

--
quan@sol.surv.utas.edu.au (Stephen Quan)
Department of Surveying (I'm actually a computer scientist.)
University of Tasmania.
--
quan@sol.surv.utas.edu.au (Stephen Quan)

vsnyder@jato.jpl.nasa.gov (Van Snyder) (06/01/91)

In article <quan.675653087@sol> quan@sol.surv.utas.edu.au (Stephen Quan) writes:
>I'm having a slight, almost trivial problem, I cannot write
>integers without them being right justified.
>
>eg  write (*,*) 5
>
>    gives
>
>    ......5   (. are leading spaces)
>
>
>Is there some format statement (i1.1 or something) that will
>solve this problem?  I want a general solution, not just :
>
>    write (*,'(i1)') 5
>
It was for exactly this reason that I urged X3J3, during all the public
reviews, to generalize format specifications so that the "w" part was
optional, as it is in "a" formats.  The committee responded that the
standard ALLOWS an implementor to do just this with * format.  But it's
hard to mix * with precise fixed formats, and, in addition, few if any
vendors left justify numbers in * format.

-- 
vsnyder@jato.Jpl.Nasa.Gov
ames!elroy!jato!vsnyder
vsnyder@jato.uucp

jerry@violet.berkeley.edu (Jerry Berkman;217E;24804;;ZA78) (06/02/91)

In article <quan.675653087@sol> quan@sol.surv.utas.edu.au (Stephen Quan) writes:
>I'm having a slight, almost trivial problem, I cannot write
>integers without them being right justified.
>
>eg  write (*,*) 5
>
>    gives
>
>    ......5   (. are leading spaces)
>
>
>Is there some format statement (i1.1 or something) that will
>solve this problem?  I want a general solution, not just :
>
>    write (*,'(i1)') 5
>
>--
>quan@sol.surv.utas.edu.au (Stephen Quan)
>Department of Surveying (I'm actually a computer scientist.)
>University of Tasmania.
>--
>quan@sol.surv.utas.edu.au (Stephen Quan)
There is no easy way to do it.  The simplest way I could do it is:

	character ctemp*40
	integer rindex

	write(ctemp,'(i40)') ival
	print 8000, ctemp(rindex(ctemp,' ')+1:),
8000	format(' ...',a,'...)

This uses a commonly available function, rindex(), which returns the
location of the last occurrence of a substring in a string.
in reverse.  If its not on your system, its easy to write.

Another alternative is to build the format on the fly.  That's
even uglier:

	character frmt*20
	data frmt/'('' ...'',iXX,''...')'/

	il = log10(float(ival))+1
	write(frmt(9:10),'(i2)') il
	print frmt, ival

This only works for positive nonzero integers and with an accurate log10().
Both methods are ugly, but I thought someone should give a solution.

	- Jerry Berkman, U.C. Berkeley, jerry@violet.berkeley.edu

userAKDU@mts.ucs.UAlberta.CA (Al Dunbar) (06/03/91)

In article <1991Jun1.043052.29008@jato.jpl.nasa.gov>, vsnyder@jato.jpl.nasa.gov (Van Snyder) writes:
>In article <quan.675653087@sol> quan@sol.surv.utas.edu.au (Stephen Quan) writes:
>>I'm having a slight, almost trivial problem, I cannot write
>>integers without them being right justified.
>>
>>eg  write (*,*) 5
>>
>>    gives
>>
>>    ......5   (. are leading spaces)
>>
>>
>>Is there some format statement (i1.1 or something) that will
>>solve this problem?  I want a general solution, not just :
>>
>>    write (*,'(i1)') 5
>>
>It was for exactly this reason that I urged X3J3, during all the public
>reviews, to generalize format specifications so that the "w" part was
>optional, as it is in "a" formats.  The committee responded that the
>standard ALLOWS an implementor to do just this with * format.  But it's
>hard to mix * with precise fixed formats, and, in addition, few if any
>vendors left justify numbers in * format.
> 
 
The same position was urged by Bert Buckley of the Fortran
Working Group of the Canadian Standards Association,
unfortunately with the same (lack of) success. I suggested a new
pair of edit specifiers, to operate similarly to BN and BZ, which
would optionally reduce all groups of blanks to a single blank on
output, regardless of the source of the blank (i.e. format string
literal, string constant or variable, or leading blanks in a
numeric field). Seems odd that such simple everyday useful things
would be left changes to the language. out, while they did deal
with much more complex and contentious
 
 -------------------+-------------------------------------------
 Al Dunbar          | 
 Edmonton, Alberta  |  Disclaimer: "not much better than
 CANADA             |                  datclaimer"    
 -------------------+-------------------------------------------

ricki@john.informatik.rwth-aachen.de (Richard Breuer) (06/04/91)

quan@sol.surv.utas.edu.au (Stephen Quan) writes:

>I'm having a slight, almost trivial problem, I cannot write
>integers without them being right justified.

>eg  write (*,*) 5

>    gives

>    ......5   (. are leading spaces)


>Is there some format statement (i1.1 or something) that will
>solve this problem?  I want a general solution, not just :

>    write (*,'(i1)') 5

>--
>quan@sol.surv.utas.edu.au (Stephen Quan)
>Department of Surveying (I'm actually a computer scientist.)
>University of Tasmania.
>--
>quan@sol.surv.utas.edu.au (Stephen Quan)

Well, there is no FORTRAN format that will do this. You can however 'create'
your own format by using an internal WRITE:

	...
	character*5 fmt
	fmt = '(i  )'
	write(fmt(3:4),'(i2)') intlen(myint)
	write(*,fmt) myint
	...

So you just need a function 'intlen' that computes the length of an
integer value in decimal digits, e.g.

	intlen(5)	=	1
	intlen(-5)	=	2
	intlen(1234)	=	4
			...

I wrote such a function some years ago. If you want it, let me know and
I will look for it.

						Hope this help, Ricki.

quan@sol.surv.utas.edu.au (Stephen Quan) (06/05/91)

ricki@john.informatik.rwth-aachen.de (Richard Breuer) writes:
>quan@sol.surv.utas.edu.au (Stephen Quan) writes:
> [..left justify by integer problem ]
>Well, there is no FORTRAN format that will do this. You can however 'create'
>your own format by using an internal WRITE:

>	...
>	character*5 fmt
>	fmt = '(i  )'
>	write(fmt(3:4),'(i2)') intlen(myint)
>	write(*,fmt) myint
>	...

>I wrote such a function some years ago. If you want it, let me know and
>I will look for it.

>						Hope this help, Ricki.

Don't worry, I was just being curious and wondered if Fortran supported
left-justify of integers.  From what I see, the answer is 'yes', only
if you are prepared to make the effort of doing it.

--
quan@sol.surv.utas.edu.au (Stephen Quan)
Department of Surveying,
University of Tasmania,
Australia.
--
quan@sol.surv.utas.edu.au (Stephen Quan)

hirchert@ncsa.uiuc.edu (Kurt Hirchert) (06/12/91)

Summary:
1. FORTRAN 77 provides no guaranteed facility for directly writing left-
   justified integers (although list-directed output may work this way in
   some implementations).

2. There are two common ways to "roll your own":

   a. Construct the format dynamically.  A function such as

            INTEGER FUNCTION WIDTH(INTEGR)
            INTEGER MAXWID
            PARAMETER (MAXWID=10)
      * 10 is the right value for 32-bit integers, since 2**31 has 10 digits.
      * 5 is the right value for 16-bit integers, since 2**15 has 5 digits.
      * When porting to a new machine, redefine MAXWID accordingly.
            DO 10 WIDTH=1,MAXWID-1
            IF (10**WIDTH .GT. ABS(INTEGR)) GO TO 20
         10 CONTINUE
         20 IF (INTEGR .LT 0) WIDTH=WIDTH+1
            END

      will usually be both faster and more accurate in determining the
      correct width.

   b. Write the integer to an internal file, and then use character
      manipulation to locate the relevant characters that you want to
      put out.

3. Fortran 90 didn't significantly change the situation, except that some
   of the new intrinsic functions make 2b easier to do.

4. Apparently, several people suggested to X3J3 that the I edit descriptor
   without a width should work this way (analogous to the A edit descriptor
   without a width).

   a. A without a width is also well defined on input.  I without a width
      does not appear to be.

   b. While X3J3 was relatively amenable to changes of this small magnitude
      early in the revision cycle, by the time of the formal public reviews,
      X3J3 was so busy dealing with major issues that unless it was
      "intuitively obvious" that this kind of small change was the right
      thing to do, there usually wasn't time to fully debate the merits of
      this kind of proposal, and such proposals were sent back to subcommittee.
      Because of that, subcommittees rarely even tried to bring such proposals
      before the full committee unless there was reason to believe that it
      would be passed with little or no opposition.  I think that 4a is
      sufficient reason to believe that there would have been opposition,
      and to the best of my knowledge, these suggestions were never brought
      out of subcommittee.
-- 
Kurt W. Hirchert     hirchert@ncsa.uiuc.edu
National Center for Supercomputing Applications