在位級別的工作上做得很好,你幾乎就在那裏。 「大Endien與小......」
https://gcc.gnu.org/onlinedocs/gfortran/CONVERT-specifier.html
http://www.lahey.com/docs/lfenthelp/F95ARINQUIREStmt.htm
https://software.intel.com/en-us/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。你可能會注意到,像我這樣做的類型15是'miCOMPRESSED',所以在那個時候需要解壓縮器來理解它。
您需要像以前一樣測試它,因爲我很容易讓訂單錯誤,而且我正在通過記憶來做這件事(更新爲我今天所做的更新,但是在子例程中,所以它應該作爲一個函數??)
我做了它4,以防你需要一個'8'版本...然後你只需調用Shifty(),你可以得到一個匹配你的數據。
沒有真正解決中心問題,但是對於現代fortran,您可以在開放時指定'access ='stream'',因此不需要處理標題數據。嘗試一下,並驗證生成的文件恰好是四個字節。 – agentp
作爲比較,我的小端系統的字節是'14 ae af 40',而數學公司將它讀作「Real32」就好了。我假設你意識到'5.49'不完全可以表示,你的實際值是'5.48998..'左右。 (不是那麼熟悉matlab,但我想'浮動'是64位,所以你會看到類似的東西。) – agentp