0

I have a data file, some of the numbers are really big, like 1E252. How do I read data into Fortran as 1D252. I've tried declaring the variable as double and kind=16, but when its read in as 1E252, it errors.

Unfortunately, the easy solution, to parse the data file and convert all Es to Ds won't work because it also needs to be compatible with python.

Is there something more elegant than this?

program test
   Integer :: i
   real (kind = 8) :: another_test
   Character(len=20) :: char_arr 
   
   char_arr = "1.10E+223"
   
   Do i = 1,20
    If (char_arr(i:i) == "E") then
         char_arr(i:i) = "D"
    EndIf
   EndDo
   Read(char_arr, *) another_test
   Write(*,*) another_test
  

end program test
user267298
  • 129
  • 9
  • Which compiler are you using? Your program without the do loop works on gfortran and silverfrost. – cup Aug 15 '20 at 07:06
  • 6
    There is no reason to change `e` to `d`: both versions are treated equally and with kind that depends only on the [variable](https://stackoverflow.com/a/33319565/3157076) it is read into. – francescalus Aug 15 '20 at 08:00
  • 1
    What error message do you get? – francescalus Aug 15 '20 at 08:03

1 Answers1

3

This isn't a full answer, mainly because I haven't been able to reproduce your premise. (I'm at my home computer, I only have access to gfortran v7.3.0 on Windows 10/cygwin.)

This code compiled perfectly fine and printed the correct value:

program large_float
    use iso_fortran_env, only: real64
    implicit none
    character(len=20) :: strrep
    real(kind=real64) :: val
    strrep  = '1.10E+223'
    read (strrep, *) val
    print *, val
end program large_float

Now you can see what I do differently to you is this: Instead of the ambiguous kind=8 I use the intrinsic iso_fortran_env to get the correct kind for 64 bit floating values. I would strongly recommend to use this syntax, as it is compiler independent1 and you will know exactly what you get.

1iso_fotran_env was added I think in Fortran 2003, but I don't know of any Fortran compiler that doesn't recognise it. If you get an error, you can still use the selected_real_kind:

integer, parameter :: real64 = selected_real_kind(R=300)
chw21
  • 7,970
  • 1
  • 16
  • 31