Хорошо, что работа на уровне бит работает так далеко, вы почти там. "Большой 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'' на open и поэтому не нужно иметь дело с данными заголовка. Попробуйте это и проверьте, что результирующий файл равен четырем байтам. – agentp
для сравнения в моей маленькой системе конца байты: «14 ae af 40» и mathematica читают ее как «Real32» просто отлично. Я предполагаю, что вы понимаете, что '5.49' не является точно представимым, а фактическое значение у вас -' 5.48998..' или около того. (не знакомы с Matlab, но я полагаю, что «плавающий» 64 бит, поэтому вы увидите что-то подобное.) – agentp