我正在将来自Fortran的浮点序列写入二进制文件,并希望以Python读取它们。使用单精度和双精度浮点数(kind = 4)和(kind = 8)都可以正常工作,但是当我尝试移动到实数(kind = 16)变量类型时,突然事情不再起作用了(数据数组填充了零) 。我在这里读到: python read 16 bytes long double from binary file np.fromfile函数需要一种解决方法。我实施了建议的更改,但仍未得到正确的结果。 Mwe Python和Fortran代码在下面。我用Python 2.7 + Numpy 1.8和Python 3.4 + Numpy 1.14尝试了相同的效果。我还检查了一下,生成的文件似乎具有正确的数据量(480字节,包含16个字节的30个浮点)。任何帮助都将受到欢迎!
Python阅读器:
UI
Fortran编写器(在Ubuntu 14.04上与gfortran 4.8.6编译)
import numpy as np
inputfilename = "fortranData.bin"
dp = 8
nVals = 30
with open(inputfilename, 'rb') as f:
# both work fine for 4 or 8 byte floats (32 and 64)
# but not for 16 byte floats (np.float128)
data = np.fromfile(f, dtype=np.float64)
data = np.frombuffer(f.read(dp*nVals), dtype=np.float64, count=nVals)
print(data)
编辑:根据要求,以下是fortranData.bin文件顶部的几行数据:
program test
implicit none
integer, parameter :: dp=8
integer, parameter :: outFileUnit=51, nPts=10, nDim=3
character(len=100) :: binaryFile="fortranData.bin"
real(kind=dp), dimension(nPts,nDim) :: data
integer :: i, j
! - generate data -
do i=1, nPts
do j=1, nDim
data(i,j) = (i-1)*nDim + j
enddo
enddo
! - open file and write data -
open(unit=outFileUnit, file=binaryFile, form='unformatted', access='direct', &
status='replace', recl=nDim*sizeof(data(1,1)))
do i=1, nPts
write(outFileUnit, rec=i) data(i,:)
enddo
end program test
答案 0 :(得分:1)
据我所知,numpy不支持IEEE Quad格式,据我所知它只需要手动转换。例如,如果您以16个字节的块为单位读取文件,则可以像这样转换块(尽管测试不佳)
def rawQuadToDouble(raw):
asint = int.from_bytes(raw, byteorder='little')
sign = (-1.0) ** (asint >> 127);
exponent = ((asint >> 112) & 0x7FFF) - 16383;
significand = (asint & ((1 << 112) - 1)) | (1 << 112)
return sign * significand * 2.0 ** (exponent - 112)