[英]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
。 我嘗試將其讀取為float32
和double
,並且將中性從小尾數改為大尾數。 有任何想法嗎?
這是我的代碼的一個簡單示例:
首先,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.