Description

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.)


Example

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


Then, on a computer with a little Endian processor (e.g. PC/Pentium running Linux), read a single 32 bit / 4 byte real data element from a direct access file written on a computer with a big Endian processor, and convert this to its intended value using native_4byte_real.


  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



Download

One can simply download the file SUBR_native_4byte_real.f90 using your browser.


Code Listing


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!           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
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!