我正在读取一个二进制文件,其中我知道一个大向量的字节位置,其中包含10^8个以上的数据样本,它们以IBM格式在4字节的实值上编写(描述了这里)。
据我所知,Fortran中的实际类型使用了最新的IEEE样例格式(1位表示符号,8位表示指数,而不是7位指数,如描述的这里格式)。因此,假设实际格式读取这些实值会给出错误的值,因此我希望将每个实数分成4个整数,每个整数占用一个字节,然后进行转换,从4个整数字节中获取IEEE示例数据。
我编写了下面的测试程序来研究这个问题,在这里,我声明了一个正的真实a1=1876752.76854及其负等价的a2=-a1,分别放入字节位置1和5 (a1和a2被声明为4字节长(kind=1))。
稍后,我从流文件中为两个相同类型的b1和b2读取相同的字节位置,但我也在相同的字节位置读取两个整数n1和n2 (各为4个字节),以查看是否可以轻松地从整数类型中获取IEEE实类型。我还读取了4个整数(每个1字节)来使用它们计算IEEE值,如下所示:
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在执行上面的代码之后,我得到了以下内容:
bytes1 = -122 24 -27 73
n1 = 1239750790
b1 = 1876752.8
bytes2 = 0 0 0 0
n2 = -907732858
b2 = -1876752.8结果表明,n2并不等于-n1 (预期的),但是当我逐字节读取字节时,字节5-8都等于零,而它们将b2正确地打印为-b1,这让我感到惊讶。我试图读取字节9,但它与预期的一样是空的。
在正确读取a2和非零整数n2的真实值时,如何获得位置5-8的零字节,有什么帮助吗?
发布于 2018-06-29 10:52:04
首先,您的程序是错误的:
% 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修正明显的错误,并避免使用单位号< 10 (这通常是一个好主意,虽然本质上与您在这里看到的错误无关),我得到
% ./a.out
bytes1 = -122 24 -27 73
n1 = 1239750790
b1 = 1876752.75
bytes2 = -122 24 -27 -55
n2 = -907732858
b2 = -1876752.75 https://stackoverflow.com/questions/51099910
复制相似问题