繁体   English   中英

从十六进制转储将Fortran实际数据类型读取到Matlab中

[英]Reading the Fortran real data type into Matlab from a hex dump

如标题所述,我正在将大量的真实数组从Fortran写入一个未格式化的文件,然后尝试将该二进制文件读入Matlab。 我已经成功地使脚本适用于字符串和整数,但是它无法从十六进制转储中正确读取我的实数。

作为测试用例,我使用数字5.49。 有趣的是,根据在线转换器40 af ae 14 ,但是当我检查hexfile时,我的代码部分正在读取14 ae af 40 我尝试将其读取为float32double ,并且将中性从小尾数改为大尾数。 有任何想法吗?

这是我的代码的一个简单示例:

首先,Fortran写语句

REAL :: floating = 5.49
open(unit = 2, file = "anxietySource", form = "unformatted", status = "new", action = "readwrite")
write(unit = 2 ) floating 

现在,Matlab读取语句

fid = fopen('anxietySource', 'rb');
h1 = fread(fid, 1, 'int32'); %this is just reading off the starter bits that tell me how long my write statement is
floating = fread(fid,1,'float32');
display(floating);
fclose(fid);

我的猜测是Fortran REAL类型有些时髦。 也许这不是一个浮点数?

比特级的工作要做得很好,到此为止,您快要完成了。 “大恩蒂恩与小...”

https://gcc.gnu.org/onlinedocs/gfortran/CONVERT-specifier.html

http://www.lahey.com/docs/lfenthelp/F95ARINQUIREStmt.htm

https://software.intel.com/zh-CN/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/270026

也可以手动移动它https://www.nsc.liu.se/~boein/f77to90/a5.html#section10

MODULE Shifty
PRIVATE

INTERFACE Shift
  MODULE PROCEDURE Shift4 !,Shift8
END INTERFACE

CONTAINS
REAL FUNCTION Shift4(MyFloat)
IMPLICIT NONE
REAL, INTENT(IN) :: MyFloat
INTEGER*4        :: Float1
INTEGER*4        :: Float2
INTEGER*4        :: Float3
INTEGER*4        :: Float4

INTEGER*4        :: MyInt
EQUIVALENCE(MyInt, MyFloat)
INTEGER*4        :: MyIntOut
EQUIVALENCE(MyIntOut, Shift4)

WRITE(*,20) MyInt
20 FORMAT('Incoming Real=',1PE12.5,' ==",Z8.8,'"')

Float1 = IBITS(MyInt, 0, 8)
Float2 = IBITS(MyInt, 8, 8)
Float3 = IBITS(MyInt,16, 8)
Float4 = IBITS(MyInt,24, 8)

WRITE(*,30) 1, Float1      !Check
WRITE(*,30) 2, Float2
WRITE(*,30) 3, Float3
WRITE(*,30) 4, Float4
30 FORMAT('Float',I1,'="',Z2.2,'"')

Float1 = ISHFT(Float1,  24)
Float2 = ISHFT(Float2,  16)
Float3 = ISHFT(Float3,   8)
Float4 = ISHFT(Float4,   0)

MyIntOut = IOR(Float1  , Float2)
MyIntOut = IOR(MyIntOut, Float3)
MyIntOut = IOR(MyIntOut, Float4)

WRITE(*,20) MyInt, MyIntOut
20 FORMAT('Incoming Real="',Z8.8,' Outgoing="',Z8.8,'"')

RETURN
END FUNCTION Shift4

END MODULE Shifty

PROGRAM MAT2F90
USE Shifty
IMPLICIT NONE

TYPE MATLAB_HEADER
  CHARACTER(LEN=120) :: Descriptor  !should be 116 and INT*8 !!
  INTEGER*4          :: Offset
  INTEGER*2          :: Version
  CHARACTER(LEN=2)   :: Endien
END TYPE MATLAB_HEADER

TYPE MATLAB_SUBHEADER
  INTEGER*4          :: Type
  INTEGER*4          :: Bytes
END TYPE MATLAB_SUB_HEADER

TYPE(MATLAB_HEADER)                   :: Head
TYPE(MATLAB_SUB_HEADER),DIMENSION(20) :: Tag
CHARACTER(LEN=12), DIMENSION(18) :: Matlab_Version =  RESHAPE(&
['miINT8      ','miUINT8     ','miINT16     ','miUINT16    ', &
 'miINT32     ','miUINT32    ','miSINGLE    ','Reserved    ', &
 'miDOUBLE    ','Reserved    ','Reserved    ','miINT64     ', &
 'miUINT64    ','miMATRIX    ','miCOMPRESSED','miUTF8      ', &
 'miUTF16     ','miUTF32     '],[18])
LOGICAL :: Swap
...
OPEN(UNIT=22,FILE='<somename>',ACCESS='STREAM',FORM='UNFORMATTED',IOSTAT=Status)
IF(Status =/0 ) ...Do something

READ(20,IOSTAT=Status) Head
IF(Status =/0 ) ...Do something

WRITE(*,*)'Head.Descriptor="',Head.Descriptor,'"'
WRITE(*,*)'Head.Offset    = ',Head.Offset
WRITE(*,*)'Head.Version   = ',Head.Version
WRITE(*,*)'Head.Endien    ="',Head.Endian,'"'
IF(Head.Endian == 'IM') THEN
  SWAP = .FALSE.
ELSEIF(Head.Endian == 'MI') THEN
  SWAP = .TRUE.
ELSE
  WRITE(*,*)'Unknown  Endien="',Head.Endian,'"'
  STOP
ENDIF

READ(20,IOSTAT=Status) Tag(1)
IF(Status =/0 ) ...Do something
WRITE(*,*)'Tag(1).Type = ',Tag(1).Type,' == "',Matlab_Version(Tag(1).Type),'"'
WRITE(*,*)'Tag(1).Bytes= ',Tag(1).Bytes
!read and swap if need be...
!There is padding to an 8type boundary
!Read the next tag and data... etc

第1-5至1-9节https://data.cresis.ku.edu/data/mat_reader/matfile_format.pdf 您可能会像我一样注意到type15是'miCOMPRESSED',因此此时需要使用解压器来理解它。

您需要像以前一样对其进行测试,因为我很容易弄错订单,而且我正在通过内存来执行此操作。(今天更新此操作,但在一个子例程中,因此它应该可以工作作为功​​能??)

如果您需要一个'8'版本,我将其设置为4 ...然后您只需调用Shifty()即可获得与您的数据匹配的版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM