Fortran 90 subroutine `native_4byte_real' for converting a 32 bit, 4 byte, REAL from big Endian to little Endian, or conversely from little Endian to big Endian. (Of course, this subprogram can also be written as a function.)
On a computer with a big Endian processor (e.g. Sun/sparc, SGI/R10000), write a single 32 bit / 4 byte real data element to a direct access file:
PROGRAM write_using_big_endian ! Writes a single 32 bit / 4 byte real data element to a direct access ! file on a computer with a big Endian processor. IMPLICIT NONE REAL, PARAMETER :: realData = 0.9734E-4 INTEGER, PARAMETER :: nbytes = 4 OPEN(UNIT=10,FILE="realData.bigE.Fda",ACCESS="DIRECT",RECL=nbytes) WRITE(10,REC=1) realData CLOSE(10) END PROGRAM write_using_big_endian |
PROGRAM read_using_little_endian ! Using a computer with a little Endian processor, this ! program reads a single 32 bit / 4 byte real data element from ! a direct access file written on a computer with a big Endian ! processor, and converts this to its intended value using ! the subroutine native_4byte_real. IMPLICIT NONE REAL :: realData INTEGER, PARAMETER :: nbytes = 4 REAL :: realDataOut OPEN(UNIT=10,FILE="realData.bigE.Fda",ACCESS="DIRECT",RECL=nbytes) READ(10,REC=1) realData CLOSE(10) ! The value of realData is, to 4 digit representation, 0.1925E-35, ! whereas on the computer with the big Endian processor, the value ! of realData was 0.9734E-4. Thus, we need to reverse the byte order ! of realData on the computer with the little Endian processor. CALL native_4byte_real( realData, realDataOut ) realData = realDataOut ! The value of realData is now 0.9734E-4, the same as on the computer ! with the big Endian processor. END PROGRAM read_using_little_endian |
One can simply download the file SUBR_native_4byte_real.f90 using your browser.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! FILE: SUBR_native_4byte_real.f90
! SUBPROGRAM: native_4byte_real
!
! AUTHOR: David Stepaniak, NCAR/CGD/CAS
! DATE INITIATED: 29 April 2003
! LAST MODIFIED: 29 April 2003
!
! SYNOPSIS: Converts a 32 bit, 4 byte, REAL from big Endian to
! little Endian, or conversely from little Endian to big
! Endian.
!
! DESCRIPTION: This subprogram allows one to convert a 32 bit, 4 byte,
! REAL data element that was generated with, say, a big
! Endian processor (e.g. Sun/sparc, SGI/R10000, etc.) to its
! equivalent little Endian representation for use on little
! Endian processors (e.g. PC/Pentium running Linux). The
! converse, little Endian to big Endian, also holds.
! This conversion is accomplished by writing the 32 bits of
! the REAL data element into a generic 32 bit INTEGER space
! with the TRANSFER intrinsic, reordering the 4 bytes with
! the MVBITS intrinsic, and writing the reordered bytes into
! a new 32 bit REAL data element, again with the TRANSFER
! intrinsic. The following schematic illustrates the
! reordering process
!
!
! -------- -------- -------- --------
! | D | | C | | B | | A | 4 Bytes
! -------- -------- -------- --------
! |
! -> 1 bit
! ||
! MVBITS
! ||
! \/
!
! -------- -------- -------- --------
! | A | | B | | C | | D | 4 Bytes
! -------- -------- -------- --------
! | | | |
! 24 16 8 0 <- bit
! position
!
! INPUT: realIn, a single 32 bit, 4 byte REAL data element.
! OUTPUT: realOut, a single 32 bit, 4 byte REAL data element, with
! reverse byte order to that of realIn.
! RESTRICTION: It is assumed that the default REAL data element is
! 32 bits / 4 bytes.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SUBROUTINE native_4byte_real( realIn, realOut )
IMPLICIT NONE
REAL, INTENT(IN) :: realIn
! a single 32 bit, 4 byte
! REAL data element
REAL, INTENT(OUT) :: realOut
! a single 32 bit, 4 byte
! REAL data element, with
! reverse byte order to
! that of realIn
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Local variables (generic 32 bit INTEGER spaces):
INTEGER :: i_element
INTEGER :: i_element_br
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Transfer 32 bits of realIn to generic 32 bit INTEGER space:
i_element = TRANSFER( realIn, 0 )
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Reverse order of 4 bytes in 32 bit INTEGER space:
CALL MVBITS( i_element, 24, 8, i_element_br, 0 )
CALL MVBITS( i_element, 16, 8, i_element_br, 8 )
CALL MVBITS( i_element, 8, 8, i_element_br, 16 )
CALL MVBITS( i_element, 0, 8, i_element_br, 24 )
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Transfer reversed order bytes to 32 bit REAL space (realOut):
realOut = TRANSFER( i_element_br, 0.0 )
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
END SUBROUTINE
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|