3

I am reading a binary file where I know the byte positions of a large vector that contains more than 10^8 data samples written on 4-byte real in IBM format (described here).

As far as I know the real types in Fortran use the more recent IEEE format of samples (1 bit for sign, 8 bits for the exponent instead of 7-bit exponent for IBM format) as described here. Therefore reading these real values assuming a real format will give me wrong values, so I want to split each real number into 4 integers each occupying a single byte and then making the transformation to get the IEEE sample data from the 4 integer bytes.

I wrote the following test program to investigate this where I declare a positive real a1=1876752.76854 and its negative equivalent a2=-a1 into byte positions 1 and 5 respectively (a1 and a2 were declared to be 4 bytes long (kind=1)).

Later I read the same byte positions from the stream file for two reals of the same kind b1 and b2, but I also read in the same byte position two integers n1 and n2 (4 bytes each) to see if I can get the IEEE real type from the integer type easily. I also read the 4 integers (1 byte each) to use them to compute IEEE values as shown below:

program test_real_types implicit none integer,parameter :: rk=kind(1.0) real(rk) :: a1,a2,b1,b2 integer(kind=1) :: bytes1(4),bytes2(4) integer :: i integer(kind=4) :: n1,n2 a1=1876752.76854 a2=-a1 open(1,file='reals.dat',access="stream",form="unformatted") write(1,pos=1) a1 write(1,pos=5) a2 close(1) open(2,file='reals.dat',access="stream",form="unformatted",status="old") !! reading byte positions: 1-4 do i=1,4 read(2,pos=i) bytes1(i) enddo read(2,pos=1) n1 !! read integer n1 of 4 bytes length in the same position read(2,pos=1) b1 !! read real (4 bytes) in the same position !! reading byte positions: 5-8 do i=5,8 read(2,pos=i) bytes2(i) enddo read(2,pos=5) n2 read(2,pos=5) b2 write(*,*) 'bytes1 = ',bytes1(1:4) write(*,*) ' n1 = ',n1 write(*,*) ' b1 = ',b1 write(*,*) 'bytes2 = ',bytes2(1:4) write(*,*) ' n2 = ',n2 write(*,*) ' b2 = ',b2 end program test_real_types 

After execution of the code above, I got the following:

 bytes1 = -122 24 -27 73 n1 = 1239750790 b1 = 1876752.8 bytes2 = 0 0 0 0 n2 = -907732858 b2 = -1876752.8 

As the results indicate, n2 is not equal to -n1 (expected), but I am surprised that bytes 5-8 are all equal to zero when I read them byte by byte while they print b2 correctly as -b1. I tried to read byte 9 but it is empty as expected.

Any help on how I am getting zero bytes for locations 5-8 while I can read correctly the real value of a2 and a non-zero integer n2?

1
  • 2
    I am puzzled by the approach to using KIND values. First it is assumed that the real is 4 bytes, but then use the parameter rk to define the precision. Then use of explicit values for integer kinds, on the basis that kind = byte count. Then Fortran file units 1 and 2 are being used. Based on recent posts, this is not an isolated example. Where is this Fortran being taught ? Should Fortran tutorials be more publicised. Commented Jun 29, 2018 at 11:29

1 Answer 1

3

First of all, your program is buggy:

% gfortran -O2 -g -Wall -fcheck=all test_real_types.f90 % ./a.out At line 30 of file test_real_types.f90 Fortran runtime error: Index '5' of dimension 1 of array 'bytes2' above upper bound of 4 

Fixing the obvious error, and also avoiding the use of unit numbers < 10 (which is a good idea in general, though per se not relevant to the error you're seeing here), I get

% ./a.out bytes1 = -122 24 -27 73 n1 = 1239750790 b1 = 1876752.75 bytes2 = -122 24 -27 -55 n2 = -907732858 b2 = -1876752.75 
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for replying. I found the error and fixed it. I run GNU Fortran (GCC) 4.4.7 on Red Hat. The compilation worked for the other options but not for -fcheck=all. What's that for?
-fcheck=all adds all kinds of runtime checks. See gcc.gnu.org/onlinedocs/gfortran/Code-Gen-Options.html . On such an old version as 4.4, you might instead try -fbounds-check which doesn't do all the checking -fcheck=all does, but does at least check array bounds.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.