Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28446 Discussions

Fortran list-directed write and read turns huge(1d0) into Infinity.

Harper__John
Beginner
961 Views

This program writes huge(1d0) to an internal file then reads it back. Both are list-directed. But reading gave Infinity, which looks like an ifort bug.  I suspect the trouble is that ifort Version  19.1.3.304 Build 20200925_000000 writes  1.797693134862316E+308,  which is > huge(1d0). With the same program gfortran gave 1.7976931348623157E+308, which is correct. Evidence:

johns-laptop:~$ cat testhuge.f90
program testhuge
implicit none
real(kind(1d0)) big,x
character(80) line
integer ios
big = huge(big)
print *,big
write(line,*) big
read(line,*,iostat=ios) x
if(ios/=0) print "(A,I0)",'iostat from internal read = ',ios
print *,x
end program testhuge

john@johns-laptop:~$ intel/bin/ifort -V testhuge.f90
Intel(R) Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.1.3.304 Build 20200925_000000
Copyright (C) 1985-2020 Intel Corporation. All rights reserved.

Intel(R) Fortran 19.1-1655
GNU ld (GNU Binutils for Ubuntu) 2.30
john@johns-laptop:~$ ./a.out
1.797693134862316E+308
Internal read iostat=64
Infinity
john@johns-laptop:~$ gfortran testhuge.f90
john@johns-laptop:~$ ./a.out
1.7976931348623157E+308
1.7976931348623157E+308
johns-laptop:~$

Labels (1)
0 Kudos
2 Replies
Steve_Lionel
Honored Contributor III
952 Views

You created this problem when you used list-directed output to write LINE. This uses a "processor-dependent" format which ends up rounding the last few digits of the value from 3157 to 316[0]. When the rounded value is read in, it is too big for a REAL(8).

If instead you did this:

write(line,'(E25.17E3)') big

you would get in LINE the value ending in 3157 and this will read correctly into X.

The moral of the story is to not use list-directed I/O when you care about the formatting.

0 Kudos
mecej4
Honored Contributor III
931 Views

Here is a similar example to reinforce what Steve L. wrote:

character(len=30) str
real x,z
x = acos(-1.0)
write(str,*)x
read(str,*)z
print *,tan(x*0.5),tan(z*0.5)
end program

The output when IFort is used:  -2.2877332E+07 -6137956.

The output from gFortran :  -22877332.0 -22877332.0

You cannot use routine evaluations and list-directed I/O with such corner cases.

 

0 Kudos
Reply