user4372504
user4372504

Reputation:

Floating point output format with leading zeros

For example, if I make these definitions:

Real, parameter :: No_01 = 2.34
Real, parameter :: No_02 = 34.56

and I want to write these variables with F format in this way:

Character(*), parameter :: FMT_01 = '(2x,F4.2)'
Character(*), parameter :: FMT_02 = '(2x,F5.2)'

The result of writing to screen would be:

Write(*, FMT_01 ) NO_01 => 2.34
Write(*, FMT_02 ) NO_02 => 34.56

Is there any kind of F format which can be used for geting this result of writing instead: Result is:

!Correct result          !Not correct result
002.340 Something         2.340 Something
034.560 Something         34.560 Something

The answers to How to pad floating point output with leading zeros? are not applicable, because the values can be negative.

Upvotes: 1

Views: 1323

Answers (3)

user4372504
user4372504

Reputation:

There is two methods for getting result from question:

Program Main

Implicit none

Open(15,File='Output.txt')

  Write(15,'(1x,a,1x,"j",1x,a,1x,"Juhu!")') Writing_01(67.45),Writing_01(-4.04)
  Write(15,'(1x,a,1x,"j",1x,a,1x,"Juhu!")') Writing_02(67.45),Writing_02(-4.04)

Close(15)

Contains

Function Writing_01 ( Deg ) Result ( Str )

Real,intent(in) :: Deg
Character(:),allocatable :: Str
Character(len = 15 ) :: Str_temp

If ( int( Deg ) > 0 ) then

    Write(Str_temp , '(F0.2)' ) 100000.0 + Deg
    Str_temp = Str_temp(2:)

Else

    Write(Str_temp, '(F0.2)' ) 100000.0 + abs(Deg)
    Str_temp = "-"//Str_temp(3:)

Endif

Str = trim ( adjustl ( Str_temp ))

End Function Writing_01

Function Writing_02 ( Deg ) Result ( Str_temp )

Real,intent(in) :: Deg
Character(:),allocatable :: Str_temp
Character(len=1561) :: Form_02 , Res

If (int( Deg ) > 0 ) then

  Form_02 = '(i5.5,f0.2)'   ! allow a total of 4 leading zeros.

Else

  Form_02 = '(i5.4,f0.2)'   ! "-" sign takes up one space, so 3 leading zeros remain.

Endif

Write(Res , Form_02 )  int( Deg ), abs( Deg - int( Deg ) )

Str_temp = trim ( adjustl ( Res ))

End Function Writing_02

End program Main

Upvotes: 0

Matt P
Matt P

Reputation: 2347

For a constant field width without leading zeros, you could just specify a format with an assumed maximum field width. The negative signs are automatically handled, and the values are right-adjusted by default. For example:

character(len=6) :: form
real :: rv1, rv2

! Format: floating point, field width=8 (includes the "."), decimal places=2
form = '(f8.2)'  
rv1  = -12.34
rv2  =  123.45

write(*,form) rv1
write(*,form) rv2

! example output. notice the two leading spaces are just blanks, but the 
! field width ("8") is constant and the ("2") decimal places are aligned:
  -12.34
  123.45

If you want to have a constant field width with leading zeros, then you must use the technique shown at this SO answer you've already linked to in your question, along with the trick suggested by @agentp in a comment. I can't tell if you quite understood, so here's a subroutine demonstrating these ideas:

subroutine leadingzeros(rv)
    real, intent(in) :: rv
    ! local vars
    character(len=11) :: form

    if (int(rv)>0) then
        form='(i4.4,f0.2)'   ! allow a total of 4 leading zeros.
    else
        form='(i4.3,f0.2)'   ! "-" sign takes up one space, so 3 leading zeros remain.
    endif

    ! handle negative values as suggested by agentp
    write(*,form) int(rv), abs(rv-int(rv))
end subroutine leadingzeros

Now, when you call leadingzeros the output looks like:

! example output from 'call leadingzeros(rv1)'
-012.34
! example output from 'call leadingzeros(rv2)'
0123.45

Upvotes: 0

Steve Lionel
Steve Lionel

Reputation: 7267

If you use F0.2 for both then you'll get:

  2.34
  34.56

Is that acceptable?

Upvotes: 1

Related Questions