Routine that converts the ASCII digits in a string to a real value author: P J Knight, CCFE, Culham Science Centre string : input string : contains digits of the number length : input integer : useful length of character string rvar : output real : value stored in the string icode : output integer : diagnostic flag This routine converts the ASCII digits in string(1:length) to the real variable rvar. The string is parsed one character at a time, from the left, handling the mantissa, and all other components of the real number separately, combining them at the end. None
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
character(len=*), | intent(in) | :: | string | |||
integer, | intent(in) | :: | length | |||
real(kind=dp), | intent(out) | :: | rval | |||
integer, | intent(out) | :: | icode |
subroutine string_to_real(string,length,rval,icode)
!! Routine that converts the ASCII digits in a string to
!! a real value
!! author: P J Knight, CCFE, Culham Science Centre
!! string : input string : contains digits of the number
!! length : input integer : useful length of character string
!! rvar : output real : value stored in the string
!! icode : output integer : diagnostic flag
!! This routine converts the ASCII digits in string(1:length)
!! to the real variable rvar.
!! The string is parsed one character at a time, from the left,
!! handling the mantissa, and all other components of the real
!! number separately, combining them at the end.
!! None
!
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
implicit none
! Arguments
character(len=*), intent(in) :: string
integer, intent(in) :: length
real(dp), intent(out) :: rval
integer, intent(out) :: icode
! Local variables
real(dp) :: valbdp,valadp,xexp
integer :: iptr,izero,iexpon
logical :: negatm,negate
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
iptr = 1
! *** Ignore leading spaces
10 continue
if (string(iptr:iptr) == ' ') then
iptr = iptr + 1
if (iptr <= length) goto 10
end if
! *** Initialise real value
rval = 0.0D0
! *** ASCII '0'
izero = ichar('0')
! *** If negative mantissa
negatm = .false.
! *** If negative exponent
negate = .false.
! *** Value before decimal point
valbdp = 0.0D0
! *** Value after decimal point
valadp = 0.0D0
! *** Exponent
iexpon = 0
! *** First character can be +, -, ., or <digit>
if (string(iptr:iptr) == '+') then
iptr = iptr + 1
if (iptr > length) goto 50
else if (string(iptr:iptr) == '-') then
iptr = iptr + 1
if (iptr > length) goto 50
negatm = .true.
else
continue
end if
! *** Parse the mantissa - before the decimal point
valbdp = 0.0D0
xexp = -1.0D0
20 continue
if ((string(iptr:iptr) >= '0').and.(string(iptr:iptr) <= '9')) then
valbdp = (valbdp * 10.0D0) + dble(ichar(string(iptr:iptr))-izero)
iptr = iptr + 1
if (iptr > length) goto 50
goto 20
end if
! *** After the mantissa, we expect '.' or 'd' or 'e'
if (string(iptr:iptr) == '.') then
iptr = iptr + 1
if (iptr > length) goto 50
end if
! *** Parse the mantissa - after the decimal point
valadp = 0.0D0
30 continue
if ((string(iptr:iptr) >= '0').and.(string(iptr:iptr) <= '9')) then
valadp = valadp + (dble(ichar(string(iptr:iptr))-izero)*(10.0D0 ** xexp))
xexp = xexp - 1.0D0
iptr = iptr + 1
if (iptr > length) goto 50
goto 30
end if
! *** Now we expect the exponent
if ( (string(iptr:iptr) == 'D').or. &
(string(iptr:iptr) == 'E').or. &
(string(iptr:iptr) == 'd').or. &
(string(iptr:iptr) == 'e')) then
iptr = iptr + 1
if (iptr > length) goto 50
! *** First character can be +, -, ., or <digit>
if (string(iptr:iptr) == '+') then
iptr = iptr + 1
if (iptr > length) goto 50
else if (string(iptr:iptr) == '-') then
iptr = iptr + 1
if (iptr > length) goto 50
negate = .true.
else
continue
end if
! *** Parse the exponent
40 continue
if ((string(iptr:iptr) >= '0').and.(string(iptr:iptr) <= '9')) then
iexpon = (iexpon * 10) + (ichar(string(iptr:iptr))-izero)
iptr = iptr + 1
if (iptr <= length) goto 40
else
goto 60
end if
else
goto 60
end if
50 continue
! *** Negative exponent?
if (negate) iexpon = -iexpon
! *** Build the number at last
if (iexpon == 0) then
rval = (valbdp + valadp)
else
rval = (valbdp + valadp) * (10.0D0 ** iexpon)
end if
! *** Negative mantissa?
if (negatm) rval = -rval
! *** All OK
icode = 0
goto 1000
! *** Errors
60 continue
write(*,*) 'Problem with IN file, please check line'
write(*,*) string
write(*,*) 'Comments should be indicated by an asterisk (*)'
error = .True.
icode = 1
1000 continue
end subroutine string_to_real