HP OpenVMS Systems Documentation

Content starts here

HP Fortran for OpenVMS
User Manual


Previous Contents Index


Chapter 9
Converting Unformatted Numeric Data

This chapter describes:

9.1 Overview of Converting Unformatted Numeric Data

You specify the floating-point format in memory with the /FLOAT qualifier. HP Fortran supports the following little endian floating-point formats in memory (default is /FLOAT=G_FLOAT):

Floating-Point Size /FLOAT=IEEE_FLOAT /FLOAT=D_FLOAT /FLOAT=G_FLOAT
KIND=4 S_float F_float F_float
KIND=8 T_float D_float G_float
KIND=16 X_float X_float X_float

If your program needs to read or write unformatted data files containing a floating-point format that differs from the format in memory for that data size, you can request that the unformatted data be converted.

For example, if your program primarily uses IEEE little endian floating-point data, specify /FLOAT=IEEE_FLOAT to specify use of the S_float, T_float, and X_float formats in memory. If your program needs to read a data file containing a different format (VAX or big endian), you need to specify which VAX or big endian floating-point format to use for conversion into the native IEEE memory format for that file.

Converting unformatted data is generally faster than converting formatted data and is less likely to lose precision for floating-point numbers.

9.2 Endian Order of Numeric Formats

Data storage in different computers use a convention of either little endian or big endian storage. The storage convention generally applies to numeric values that span multiple bytes, as follows:

  • Little endian storage occurs when:
    • The least significant bit (LSB) value is in the byte with the lowest address.
    • The most significant bit (MSB) value is in the byte with the highest address.
    • The address of the numeric value is the byte containing the LSB. Subsequent bytes with higher addresses contain more significant bits.
  • Big endian storage occurs when:
    • The least significant bit (LSB) value is in the byte with the highest address.
    • The most significant bit (MSB) value is in the byte with the lowest address.
    • The address of the numeric value is the byte containing the MSB. Subsequent bytes with higher addresses contain less significant bits.

Figure 9-1 shows the difference between the two byte-ordering schemes.

Figure 9-1 Little and Big Endian Storage of an INTEGER Value


Moving data files between big endian and little endian computers requires that the data be converted.

9.3 Native and Supported Nonnative Numeric Formats

HP Fortran provides the capability for programs to read and write unformatted data (originally written using unformatted I/O statements) in several nonnative floating-point formats and in big endian INTEGER or floating-point format.

When reading a nonnative unformatted format, the nonnative format on disk must be converted to native format in memory. Similarly, native data in memory can be written to a nonnative unformatted format. If a converted nonnative value is outside the range of the native data type, a run-time message appears (listed in Section 7.2).

Supported native and nonnative floating-point formats include:

  • Standard IEEE little endian floating-point formats1 and little endian integers. This format is found on HP OpenVMS I64 systems, HP OpenVMS Alpha systems, HP Tru64 UNIX systems, and Microsoft Windows operating systems (for IBM-compatible PC systems).
  • Standard IEEE big endian floating-point formats1 and big endian integers found on most Sun systems, HP-UX systems, and IBM RISC System/6000 systems.
  • VAX little endian floating-point formats and little endian integers supported by Compaq Fortran 77 and HP Fortran for OpenVMS I64 and Alpha systems and Compaq Fortran 77 for OpenVMS VAX systems. (OpenVMS VAX systems use a different 16-byte REAL format.)
  • Big endian proprietary floating-point formats and big endian integers associated with CRAY (CRAY systems).
  • Big endian proprietary floating-point formats and big endian integers associated with IBM (the IBM's System\370 and similar systems).

The native memory format uses little endian integers and little endian floating-point formats, as follows:

  • INTEGER and LOGICAL declarations of one, two, four, or eight bytes (intrinsic kinds 1, 2, 4, and 8). You can specify the integer data length by using an explicit data declaration (kind parameter or size specifier). All INTEGER and LOGICAL declarations without a kind parameter or size specifier will be four bytes in length. To request an 8-byte size for all INTEGER and LOGICAL declarations without a kind parameter or size specifier, use a FORTRAN command qualifier (see Section 8.2.1).
  • The following floating-point sizes and formats are available:
    • Single-precision 4-byte REAL and 8-byte COMPLEX declarations (KIND=4) in either IEEE S_float or VAX F_float formats. This is the default size for all REAL or COMPLEX declarations without a kind parameter or size specifier.
    • Double-precision 8-byte REAL and 16-byte COMPLEX declarations (KIND=8) in IEEE T_float, VAX G_float, or VAX D_float formats. This is the default size for all DOUBLE PRECISION declarations.
    • Extended-precision 16-byte REAL declarations and 32-byte COMPLEX declarations (KIND=16) in IEEE-like X_float format.

    You can specify the real or complex data length by using an explicit data declaration (kind parameter or size specifier). You can change the default size for REAL, COMPLEX, and DOUBLE PRECISION declarations by using FORTRAN command qualifiers (/REAL_SIZE or /DOUBLE_SIZE).

Table 9-1 lists the keywords for the supported unformatted file data formats. Use the appropriate keyword after the /CONVERT qualifier (such as /CONVERT=CRAY) or as an logical name value (see Section 9.5).

Table 9-1 Unformatted Numeric Formats, Keywords, and Supported Data Types
Recognized Keyword Description
BIG_ENDIAN Big endian integer data of the appropriate INTEGER size (one, two, or four bytes) and big endian IEEE floating-point formats for REAL and COMPLEX single- and double-precision numbers. INTEGER (KIND=1) or INTEGER*1 data is the same for little endian and big endian.
CRAY Big endian integer data of the appropriate INTEGER size (one, two, four, or eight bytes) and big endian CRAY proprietary floating-point format for REAL and COMPLEX single- and double-precision numbers.
IBM Big endian integer data of the appropriate INTEGER size (one, two, or four bytes) and big endian IBM proprietary floating-point format for REAL and COMPLEX single- and double-precision numbers.
FDX Native little endian integers of the appropriate INTEGER size (one, two, four, or eight bytes) and the following native little endian proprietary floating-point formats:
F_float for REAL (KIND=4) and COMPLEX (KIND=4)
D_float for REAL (KIND=8) and COMPLEX (KIND=8)
IEEE-like X_float for REAL (KIND=16) and COMPLEX (KIND=16)

For information on these native OpenVMS formats, see Table 8-1 and Section 8.4.

FGX Native little endian integers of the appropriate INTEGER size (one, two, four, or eight bytes) and the following native little endian proprietary floating-point formats:
F_float for REAL (KIND=4) and COMPLEX (KIND=4)
G_float for REAL (KIND=8) and COMPLEX (KIND=8)
IEEE-like X_float for REAL (KIND=16) and COMPLEX (KIND=16)

For information on these native OpenVMS formats, see Table 8-1 and Section 8.4.

LITTLE_ENDIAN Little endian integers of the appropriate INTEGER size (one, two, four, or eight bytes) and the following native little endian IEEE floating-point formats:
S_float for REAL (KIND=4) and COMPLEX (KIND=4)
T_float for REAL (KIND=8) and COMPLEX (KIND=8)
IEEE-like X_float for REAL (KIND=16) and COMPLEX (KIND=16)

For information on these native OpenVMS formats, see Table 8-1 and Section 8.4.

NATIVE No conversion occurs between memory and disk. This is the default for unformatted files.
VAXD Native little endian integers of the appropriate INTEGER size (one, two, four, or eight bytes) and the following little endian VAX proprietary floating-point formats:
F_float for REAL (KIND=4) and COMPLEX (KIND=4)
D_float for REAL (KIND=8) and COMPLEX (KIND=8)
H_float for REAL (KIND=16)

For information on the F_float and D_float formats, see Table 8-1 and Section 8.4. For information on the H_float format (available only on VAX systems), see Section B.8.

VAXG Native little endian integers of the appropriate INTEGER size (one, two, four, or eight bytes) and the following little endian VAX proprietary floating-point formats:
F_float format for REAL (KIND=4) and COMPLEX (KIND=4)
G_float format for REAL (KIND=8) and COMPLEX (KIND=8)
H_float format for REAL (KIND=16)

For information on the F_float and D_float formats, see Table 8-1 and Section 8.4. For information on the H_float format (available only on VAX systems), see Section B.8.

While this solution is not expected to fulfill all floating-point conversion needs, it provides the capability to read and write various types of unformatted nonnative floating-point data.

For More Information:

  • On ranges and the format of native IEEE floating-point data types, see Table 8-1 and Section 8.4.
  • On ranges and the format of VAX floating-point data types, see Section B.8.
  • On specifying the size of INTEGER declarations (without a kind) using an FORTRAN command qualifier, see Section 8.2.1.
  • On specifying the size of LOGICAL declarations (without a kind) using an FORTRAN command qualifier, see Section 8.3.
  • On specifying the size of REAL or COMPLEX declarations (without a kind) using an FORTRAN command qualifier, see Section 8.4.1.
  • On data declarations and other HP Fortran language information, see the HP Fortran for OpenVMS Language Reference Manual.

Note

1 IEEE floating-point formats are defined in the IEEE Standard for Binary Floating-Point Arithmetic, ANSI/IEEE Standard 754-1985, Institute of Electrical and Electronics Engineers, August 1985.

9.4 Limitations of Numeric Conversion

The HP Fortran floating-point conversion solution is not expected to fulfill all floating-point conversion needs.

Data (variables) in record structures (specified in a STRUCTURE statement) and data components of derived types (TYPE statement) are not converted. When variables are later examined as separate fields by the program, they will remain in the binary format they were stored in on disk, unless the program is modified.

If a program reads an I/O record containing multiple floating-point fields into an integer array (instead of their respective variables), the fields will not be converted. When they are later examined as separate fields by the program, they will remain in the binary format they were stored in on disk, unless the program is modified. To convert floating-point formats for individual fields, consider using the CVT$CONVERT_FLOAT routine (see Example B-1).

With EQUIVALENCE statements, the data type of the variable named in the I/O statement is used.

9.5 Methods of Specifying the Unformatted Numeric Format

The methods you can use to specify the type of numeric floating-point format are as follows:

  • Set a logical name for a specific unit number before the file is opened. The logical name is named FOR$CONVERTnnn, where nnn is the unit number.
  • Set a logical name for a specific file name extension before the file is opened. The logical name is named FOR$CONVERT.ext (or FOR$CONVERT_ext), where ext is the file name extension (suffix).
  • Add the CONVERT specifier to the OPEN statement for a specific unit number.
  • Compiling the program with an OPTIONS statement that specifies the /CONVERT=keyword qualifier. This method affects all unit numbers using unformatted data specified by the program.
  • Compiling the program with the FORTRAN command /CONVERT=keyword qualifier. This method affects all unit numbers using unformatted data specified by the program.

If you specify more than one method, the order of precedence when you open a file with unformatted data is:

  1. Check for a logical name for a specific unit number
  2. Check for a FOR$CONVERT.ext logical name and then for a FOR$CONVERT_ext logical name (if the former logical name is not found)
  3. Check for the OPEN statement CONVERT specifier
  4. Check whether an OPTIONS statement with a /CONVERT=(keyword) qualifier was present when the program was compiled
  5. Check whether the FORTRAN command /CONVERT=(keyword) qualifier was used when the program was compiled

If none of these methods are specified, no conversion occurs between disk and memory. Data should therefore be in the native memory format (little endian integer and little endian IEEE or VAX format) or otherwise translated by the application program.

Any keyword listed in Table 9-1 can be used with any of these methods.

9.5.1 Logical Name FOR$CONVERTnnn Method

You can use the logical name method to specify multiple formats in a single program, usually one format for each unit number. You specify the numeric format at run time by setting the appropriate logical name before you open that unit number. For unit numbers that contain fewer than three digits, use leading zeros.

For example, to specify the numeric format for unit 9, set logical name FOR$CONVERT009 to the appropriate value (such as BIG_ENDIAN) before you run the program. For unit 125, set the logical name FOR$CONVERT125 before you run the program.

When you open the file, the logical name is always used, since this method takes precedence over the FORTRAN command qualifier methods. For instance, you might use this method to specify that different unformatted numeric formats for different unit numbers (perhaps in a command procedure that sets the logical name before running the program).

For example, assume you have a previously compiled program that reads numeric data from unit 28 and writes it to unit 29 using unformatted I/O statements. You want the program to read nonnative big endian (IEEE floating-point) format from unit 28 and write that data in native little endian format to unit 29.

In this case, the data is converted from big endian IEEE format to native little endian IEEE memory format (S_float and T_float) when read from unit 28, and then written without conversion in native little endian IEEE format to unit 29. The FORTRAN command qualifier /FLOAT specifies the IEEE floating-point format in memory and the LINK command creates the executable program:


$ FORTRAN/FLOAT=IEEE_FLOAT CONV_IEEE
$ LINK CONV_IEEE

Without requiring source code modification of recompilation of this program, the following DCL command sequence sets the appropriate logical name and then runs the program CONV_IEEE.EXE:


$ DEFINE FOR$CONVERT028 BIG_ENDIAN
$ DEFINE FOR$CONVERT029 NATIVE
$ RUN CONV_IEEE

Figure 9-2 shows the data formats used on disk and in memory when the example file conv_ieee.exe is run after the logical names are set with DCL commands.

Figure 9-2 Sample Unformatted File Conversion


For information on the DCL commands you can use to define and deassign logical names, see Appendix D.

9.5.2 Logical Name FOR$CONVERT.ext (and FOR$CONVERT_ext) Method

You can use this method to specify formats in a single program, usually one format for each specified file name extension (suffix). You specify the numeric format at run time by setting the appropriate logical name before an implicit or explicit OPEN statement to one or more unformatted files.

For example, assume you have a previously compiled program that reads floating-point numeric data from one file and writes to another file using unformatted I/O statements. You want the program to read nonnative big endian (IEEE floating-point) format from a file with a .dat file extension suffix and write that data in native little endian format to a file with a suffix of .data. You would DEFINE FOR$CONVERT.DAT BIG_ENDIAN.

In this case, the data is converted from big endian IEEE format to native little endian IEEE memory format when read from file.dat, and then written without conversion in native little endian IEEE format to the file with a suffix of .data, assuming that logical names FOR$CONVERT.DATA and FOR$CONVERTnnn (for that unit number) are not defined.

The FOR$CONVERTnnn method takes precedence over this method. When the appropriate logical name is set when you open the file, the FOR$CONVERT.ext logical name is used if a FOR$CONVERTnnn logical name is not set for the unit number.

The FOR$CONVERTnnn and FOR$CONVERT.ext (or FOR$CONVERT_ext) logical name methods take precedence over the other methods. For instance, you might use this method to specify that a unit number will use a particular format instead of the format specified in the program (perhaps for a one-time file conversion).

See Example 9-1.

Example 9-1 Example Showing the Use of the FOR$CONVERT.ext Method

Source program:

program p
   integer i
   real    r
   open( file='convert_in.txt',  unit=10)
   open( file='convert_out.big', unit=11, form="unformatted")
   open( file='convert_out.dat', unit=12, form="unformatted")
   do i = 1, 10
      read(10,*) r     ! In text
      type *,r
      write(11) r      ! In BIG_ENDIAN
      write(12) r      ! In NATIVE
   enddo
   close(10)
   close(11)
   close(12)
   end

Assume the following data in the file convert_in.txt :


1
2
3
4
5
6
7
8
9
10

Define the following symbols:


$ def for$convert.big big_endian
$ def for$convert.dat native

Then after you run the compiled source program, you get the following output:


1.000000
2.000000
3.000000
4.000000
5.000000
6.000000
7.000000
8.000000
9.000000
10.00000

And the following data in the big endian output file convert_out.big :


?
@
@@
@
@ 
@À
@à
A
A
A

And the following data in the native output file convert_out.dat :


@
A
@A
A
 A
ÀA
àA
B
B
 B

9.5.3 OPEN Statement CONVERT='keyword' Method

You can use the OPEN statement method to specify multiple formats in a single program, usually one format for each specified unit number. This method requires an explicit file OPEN statement to specify the numeric format of the file for that unit number.

This method takes precedence over the /CONVERT=keyword method (see Section 9.5.5), but has a lower precedence than the logical name method.

The following source code shows an OPEN statement coded for unformatted VAXD numeric data (read from unit 15), and an OPEN statement coded for unformatted native little endian format (written to unit 20). The absence of the CONVERT specifier (in the second OPEN statement) or logical name FOR$CONVERT020 indicates native little endian data for unit 20:


  OPEN (CONVERT='VAXD', FILE='graph3.dat', FORM='UNFORMATTED', UNIT=15)
  .
  .
  .
  OPEN (FILE='graph3_ieee.dat', FORM='UNFORMATTED', UNIT=20)

A hard-coded OPEN statement CONVERT specifier keyword value cannot be changed after compile time. However, to allow selection of a particular format at run time, you can equate the CONVERT specifier to a variable and provide the user with a menu that allows selection of the appropriate format (menu choice sets the variable) before the OPEN occurs.

You can also select a particular format for a unit number at run time by using the logical name method (see Section 9.5.1), which takes precedence over the OPEN statement CONVERT specifier method.

You can issue an INQUIRE statement (by unit number) to an opened file to obtain the current CONVERT method in use.


Previous Next Contents Index