Chapter 2. Constants and Data Structures

This chapter discusses the various types of Fortran constants and provides examples of each. It also explains a few of the ways data can be structured, including character substrings, records, and arrays.

This chapter contains the following sections:

Constants

A constant is a data value that cannot change during the execution of a program. It can be of the following types:

  • arithmetic

  • logical

  • character

  • Hollerith

  • bit

The form in which a constant is written specifies both its value and its data type. A symbolic name can be assigned for a constant using the PARAMETER statement. Blank characters occurring within a constant are ignored by the processor unless the blanks are part of a character constant.

The sections that follow describe the various types of constants in detail.

Arithmetic Constants

The Fortran compiler supports the following types of arithmetic constants:

  • integer

  • real

  • double precision

  • quad precision

  • complex

  • double complex

  • quad complex

An arithmetic constant can be signed or unsigned. A signed constant has a leading plus or minus sign to denote a positive or negative number. A constant that can be either signed or unsigned is called an optionally signed constant. Only arithmetic constants can be optionally signed.


Note: The value zero is neither positive nor negative; a signed zero has the same value as an unsigned zero.


Integer Constants

An integer constant is a whole number without decimal points; it can have a positive, negative, or zero value. Hexadecimal and octal integer constants are extensions to the standard integer constant.

The format for an integer constant is the following:

sww

where s is the sign of the number: - for negative, + (optional) for positive and ww is a whole number.

In Fortran, integer constants must comply with the following rules:

  • It must be a whole number, that is, without a fractional part.

  • If negative, the special character minus (-) must be the leading character. The plus sign (+) in front of positive integers is optional.

  • It must not contain embedded commas.

The following are examples of valid integer constants:

0 +0   +176   -1352   06310   35 

The following are examples of invalid integer constants:

2.03

Decimal point not allowed. This is a real constant (described later in this chapter).

7,909

Embedded commas not allowed.

The Fortran compiler also supports Fortran 90-style integer constants, where _n is appended to indicate the size. For example, 456_8 is an INTEGER*8 constant with the value 456.

Hexadecimal Integer Constants

Use hexadecimal integer constants for a base 16 radix. Specify a dollar sign ($) as the first character, followed by any digit (0 through 9) or the letters A through F (either uppercase or lowercase). The following are valid examples of hexadecimal integer constants:

$0123456789
$ABCDEF
$A2B2C3D4

You can use hexadecimal integer constants wherever integer constants are allowed. In mixed-mode expressions, the compiler converts these constants from type integer to the dominant type of expression in which they appear.

Octal Integer Constants

Use octal integer constants for a base 8 radix. The type of an octal integer constant is INTEGER, in contrast to the octal constant described in “Bit Constants”. This constant is supported to provide compatibility with PDP-11 Fortran.

The format of an octal constant is as follows:

o"string"

where string is one or more digits in the range of 0 through 7.

Real Constants

A real constant is a number containing a decimal point, exponent, or both; it can have a positive, negative, or zero value.

A real constant can have the following forms:

sww.ff

Basic real constant

sww.ffEsee

Basic real constant followed by a real exponent

swwEsee

Integer constant followed by a real exponent

The argument values are the following:

s

the sign of the number: - for negative, + (optional) for positive.

ww

a string of digits denoting the whole number part, if any.

ff

a string of digits denoting the fractional part, if any.

Esee

a real exponent, where see is an optionally signed integer.

A basic real constant is written as an optional sign followed by a string of decimal digits containing an optional decimal point. There must be at least one digit.

A real exponent is a power of ten.

The value of a real constant is either the basic real constant or, for the forms sww.ffEsee and swwEsee, the product of the basic real constant or integer constant and the power of ten indicated by the exponent following the letter E.

All three forms can contain more digits than the precision used by the processor to approximate the value of the real constant. See the MIPSpro Fortran 77 Programmer's Guide, for information on the magnitude and precision of a real number.

Table 2-1 illustrates real constants written in common and scientific notation with their corresponding E format.

Table 2-1. Notation Forms for Real Constants

Common Notation

Scientific Notation

Real Exponent Form

5.0

0.5*10

.5E1 or 0.5E1

364.5

3.465*102

.3645E3

49,300

4.93*104

.493E5

-27,100

-2.71*104

-.271E5

-.0018

-1.8*10-3

-.18E-2

The following real constants are equivalent:

5E4    5.E4    .5E5    5.0E+4    +5E04    50000. 

Table 2-2 lists examples of invalid real constants and the reasons they are invalid.

Table 2-2. Invalid Real Constants

Invalid Constant

Reason Invalid

-18.3E

No exponent following the E

E-5

Exponent part alone

6.01E2.5

Exponent part must be an integer

3.5E4E2

Only one exponent part allowed per constant

19,850

Embedded commas not allowed


Double-Precision Constants

A double-precision constant is similar to a real constant except that it can retain more digits of the precision and has a greater range than a real constant. The size and value ranges of double-precision constants are given in the MIPSpro Fortran 77 Programmer's Guide.

A double-precision constant assumes a positive, negative, or zero value in one of the following forms:

swwDsee

An integer constant followed by a double-precision exponent

sww.ffDsee

A basic real constant followed by a double-precision exponent

where

s

is an optional sign.

ww

is a string of digits denoting the whole number part, if any.

ff

is a string of digits denoting the fractional part, if any.

Dsee

denotes a double-precision exponent where see is an optionally signed exponent.

The value of a double-precision constant is the product of the basic real constant part or integer constant part and the power of ten indicated by the integer following the letter D in the exponent part. Both forms can contain more digits than those used by the processor to approximate the value of a real constant. See the MIPSpro Fortran 77 Programmer's Guide for information on the magnitude and precision of a double-precision constant.

Valid forms of double-precision constants are

1.23456D3
8.9743D0
-4.D-10
16.8D-6 

For example, the following forms of the numeric value 500 are equivalent:

5D2  +5D02  5.D2  5.D+02  5D0002 

Table 2-3 lists examples of invalid double-precision constants and the reasons they are invalid.

Table 2-3. Invalid Double-Precision Constants

Invalid Constant

Reason Invalid

2.395D

No exponent following the D

-9.8736

Missing D exponent designator

1,010,203D0

Embedded commas not allowed


Quad-Precision Constants

A quad-precision constant is similar to a double-precision constant except that it can retain more digits of the precision than a real constant. The MIPSpro Fortran 77 Programmer's Guide lists the size and value ranges of quad-precision constants.

A quad-precision constant assumes a positive, negative, or zero value in one of the following forms:

swwQsee

An integer constant followed by a quad-precision exponent

sww.ffQsee

A basic real constant followed by a quad-precision exponent

The argument values can be the following:

s

an optional sign.

ww

a string of digits denoting the whole number part, if any.

ff

a string of digits denoting the fractional part, if any.

Qsee

a quad-precision exponent where see is an optionally signed exponent.

The value of a quad-precision constant is the product of the basic real constant part or integer constant part and the power of ten indicated by the integer following the letter Q in the exponent part. Both forms can contain more digits than those used by the processor to approximate the value of the real constant. Refer to the MIPSpro Fortran 77 Programmer's Guide, for information on the magnitude and precision of a quad-precision constant.

Valid forms of quad-precision constants are

1.23456Q3
7.7743Q0
-2.Q-10
1.8Q-2 

For example, the following forms of the numeric value 500 are equivalent:

5Q2  +5Q02  5.Q2  5.Q+02  5Q0002 

Table 2-4 lists examples of invalid quad-precision constants and the reasons they are invalid.

Table 2-4. Invalid Quad-Precision Constants

Invalid Constant

Reason Invalid

2.395Q

No exponent following the Q

-9.8736

Missing Q exponent designator

1,010,203Q0

Embedded commas not allowed


Complex Constants

A complex constant is a processor approximation of the value of a complex number. It is represented as an ordered pair of REAL*4 data values. The first value represents the real part of the complex number, and the second represents the imaginary part. Each part has the same precision and range of allowed values as REAL*4 data.

A complex constant has the form (m,n) where m and n each have the form of a REAL*4, representing the complex value m + ni, where i is the square root of -1. The form m denotes the real part; n denotes the imaginary part. Both m and n can be positive, negative, or zero. Table 2-5 shows examples of valid forms of complex data.

Table 2-5. Valid Forms of Complex Data

Valid Complex Constant

Equivalent Mathematical Expression

(3.5, -5)

3.5 -5i

(0, -1)

- i

(0.0, 12)

0 + 12i or 12i

(2E3, 0)

2000 + 0i or 2000

Table 2-6 provides examples of invalid constants and lists the reasons they are invalid.

Table 2-6. Invalid Forms of Complex Data

Invalid Constant

Reason Invalid

(1, )

No imaginary part

(1, 2.2, 3)

More than two parts

(1.15, 4E)

Imaginary part has invalid form


Double-Complex Constants

A double-complex constant is a processor approximation of the value of a complex number. It is represented as an ordered pair of REAL*8 data values. The first value represents the real part of the complex number, and the second represents the imaginary part. Each part has the same precision and range of allowed values as REAL*8 data.

A double-complex constant has the form (m, n) where m and n each have the form of a REAL*8, representing the complex value m + ni, where i is the square root of -1. The form m denotes the real part; n denotes the imaginary part. Both m and n can be positive, negative, or zero. Refer to Table 2-7 for examples of valid forms of double-complex data.

Table 2-7. Valid Forms of Double-Complex Data

Valid Complex Constant

Equivalent Mathematical Expression

(3.5, -5)

3.5 -5i

(0, -1)

- i

(0.0, 12)

0 + 12i or 12i

(2D3, 0)

2000 + 0i or 2000

Table 2-8 shows examples of invalid constants and lists the reasons they are invalid.

Table 2-8. Invalid Forms of Double-Complex Data

Invalid Constant

Reason Invalid

(1, )

No imaginary part

(1, 2.2, 3)

More than two parts

(1.15, 4E)

Imaginary part has invalid form


Quad-Complex Constants

A quad-complex constant is a processor approximation of the value of a complex number. It is represented as an ordered pair of REAL*16 data values. The form is the same as the double-complex constant, with a Q replacing the D. The following is an example of a valid quad-complex representation of 2000 + 0i:

(2Q3,0)

Logical Constants

Logical constants represent only the values true or false, represented by one of the following forms:

Form

Value

.TRUE.

True

.FALSE.

False

Character Constants

A character constant is a string of one or more characters that can be represented by the processor. Each character in the string is numbered consecutively from left to right beginning with 1.


Note: The quotation mark (") is an extension to FORTRAN 77.

If the delimiter is ", then a quotation mark within the character string is represented by two consecutive quotation marks with no intervening blanks.

If the delimiter is ', then an apostrophe within the character string is represented by two consecutive apostrophes with no intervening blanks.

Blanks within the string of characters are significant.

The case of alphabetic characters is significant.

The length of a character constant is the number of characters, including blanks, between the delimiters. The delimiters are not counted, and each pair of apostrophes or quotation marks between the delimiters counts as a single character.

A character constant is normally associated with the CHARACTER data type. The FORTRAN 77 standard is extended (except as noted below) to allow character constants to appear in the same context as a numeric constant. A character constant in the context of a numeric constant is treated the same as a Hollerith constant.


Note: Character constants cannot be used as actual arguments to numeric typed dummy arguments.

Table 2-9 provides examples of valid character constants and shows how they are stored.

Table 2-9. Valid Character Constants

Constant

Stored as

'DON''T'

DON'T

"I'M HERE!"

I'M HERE!

'STRING'

STRING

'LMN""OP'

LMN""OP

Table 2-10 lists examples of invalid character constants and the reasons they are invalid.

Table 2-10. Invalid Character Constants

Invalid Constant

Reason Invalid

'ISN.T

Terminating delimiter missing

.YES'

Mismatched delimiters

CENTS

Not enclosed in delimiters

''

Zero length not allowed

""

Zero length not allowed


Hollerith Constants

Use Hollerith constants to manipulate packed character strings in the context of integer data types. A Hollerith constant consists of a character count followed by the letter H (either uppercase or lowercase) and a string of characters as specified in the character count and has the following format:

nHxxx...x

where n is a nonzero, unsigned integer constant and where xrepresents a string of exactly n contiguous characters. The blank character is significant in a Hollerith constant.

The following are examples of valid Hollerith constants:

3H A
10H'VALUE = '
8H MANUAL 

Table 2-11 provides some examples of invalid Hollerith constants and the reasons they are invalid.

Table 2-11. Invalid Hollerith Constants

Invalid Constant

Reason Invalid

2H YZ

Blanks are significant; should be 3H YZ

-4HBEST

Negative length not allowed

0H

Zero length not allowed

The following rules apply to Hollerith constants:

  • Hollerith constants are stored as byte strings; each byte is the ASCII representation of one character.

  • Hollerith constants have no type; they assume a numeric data type and size depending on the context in which they are used.

  • When used with a a binary operator, octal and hexadecimal constants assume the data type of the other operand. For example,

    INTEGER*2 HILO
    HILO = ZHFFX

    The constant is assumed to be of type INTEGER*2.

  • In other cases, when used in statements that require a specific data type, the constant is assumed to be the required type and length.

  • A length of four bytes is assumed for hexadecimal and octal constants used as arguments; no data type is assumed.

  • In other cases, the constant is assumed to be of type INTEGER*4.

  • When a Hollerith constant is used in an actual parameter list of a subprogram reference, the formal parameter declaration within that subprogram must specify a numeric type, not a character type.

  • A variable can be defined with a Hollerith value through a DATA statement, an assignment statement, or a READ statement.

  • The number of characters (n) in the Hollerith constant must be less than or equal to g, the maximum number of characters that can be stored in a variable of the given type, where g is the size of the variable expressed in bytes. If n <g, the Hollerith constant is stored and extended on the right with (g-n) blank characters.

  • The case of alphabetic characters is significant.

Bit Constants

You can use bit constants anywhere numeric constants are allowed. Table 2-12 shows the allowable bit constants and their format. In this table, b, o, x, and z can be lower- or uppercase (B, O, X, Z)

Table 2-12. Valid Substring Examples

Format

Meaning

Valid substring Characters

Maximum

b' string' or 'string'b

Binary

0, 1

64

O' string' or 'string'o

Octal

0 - 7

22

x' string' or 'string'x

Hexadecimal

0 - 9; a - f

16

z' string' or 'string'z

Hexadecimal

0 - 9; a - f

16

The following are examples of bit constants used in a DATA statement.

integer a(4)
data a/b'1010',o'12',z'a',x'b'/

The above statement initializes the first elements of a four-element array to binary, the second element to an octal value, and the last two elements to hexadecimal values.

The following rules apply to bit constants:

  • Bit constants have no type; they assume a numeric data type and size depending on the context in which they are used.

  • When used with a binary operator, octal, and hexadecimal constants assume the data type of the other operand. For example,

    INTEGER*2 HILO
    HILO = 'FF'X

    The constant is assumed to be of type INTEGER*2.

  • In other cases, when used in statements that require a specific data type, the constant is assumed to be the required type and length.

  • A length of four bytes is assumed for hexadecimal and octal constants used as arguments; no data type is assumed.

  • In other cases, the constant is assumed to be of type INTEGER*4.

  • A hexadecimal or octal constant can specify up to 16 bytes of data.

  • Constants are padded with zeros to the left when the assumed length of the constant is more than the digits specified by the constant. Constants are truncated to the left when the assumed length is less than that of the digits specified.

Records and Structures

The record-handling extension enables you to declare and operate on multifield records in Fortran programs. Avoid confusing the term record as it is used here with the term record that describes input and output data records.

Overview of Records and Structures

A record is a composite or aggregate entity containing one or more record elements or fields. Each element of a record is usually named. References to a record element consist of the name of the record and the name of the desired element. Records allow you to organize heterogeneous data elements within one structure and to operate on them either individually or collectively. Because they can be composed of heterogeneous data elements, records are not typed like arrays are.

You define the form of a record with a group of statements called a structure definition block. Establish a structure declaration in memory by specifying the name of the structure in a RECORD statement. A structure declaration block can include one or more of the following items

  • typed data declarations (variables or arrays)

  • substructure declarations

  • mapped field declarations

  • unnamed fields

The following sections describe these items. See the RECORD and STRUCTURE declarations block sections in Chapter 4, “Specification Statements” for details on specifying a structure in a source program.

Typed Data Declarations (Variables or Arrays)

Typed data declarations in structure declarations have the form of normal Fortran typed data declarations. You can freely intermix different types of data items within a structure declaration.

Substructure Declarations

Establish substructures within a structure by using either a nested structure declaration or a RECORD statement.

Mapped Field Declarations

Mapped field declarations are made up of one or more typed data declarations, substructure declarations (structure declarations and RECORD statements), or other mapped field declarations. A block of statements, called a union declaration, defines mapped field declarations. Unlike typed data declarations, all mapped field declarations that are made within a single union declaration share a common location within the containing structure.

Unnamed Fields

Declare unnamed fields in a structure by specifying the pseudo-name %FILL in place of an actual field name.%FILL generates empty space in a record for purposes such as alignment.

Record and Field References

The generic term scalar reference refers to all references that resolve to single typed data items. A scalar field reference of an aggregate falls into this category. The generic term aggregate reference is used to refer to all references that resolve to references of structured data items defined by a RECORD statement.

Scalar field references can appear wherever normal variables or array elements can appear, with the exception of COMMON, SAVE, NAMELIST, and EQUIVALENCE statements. Aggregate references can only appear in aggregate assignment statements, in unformatted I/O statements, and as parameters to subprograms.

Aggregate Assignment Statement

Aggregates can be assigned as whole entities. This special form of the assignment statement is indicated by an aggregate reference on the left-hand side of an assignment statement and requires an identical aggregate to appear on the right-hand side of the assignment.

Arrays

An array is a non-empty sequence of data of the same type occupying consecutive bytes in storage. A member of this sequence of data is referred to as an array element.

Each array has the following characteristics:

  • array name

  • data type

  • array elements

  • array declarator specifying:

    • number of dimensions

    • size and bounds of each dimension

Define an array using a DIMENSION, COMMON, or type statement (described in Chapter 4, “Specification Statements”); it can have a maximum of seven dimensions.


Note: For information on array handling when interacting with programs written in another language, see the MIPSpro Fortran 77 Programmer's Guide.


Array Names and Types

An array name is the symbolic name given to the array and must conform to the rules given in Chapter 1, “Fortran Elements and Concepts” for symbolic names. When referencing the array as a whole, specify only the array name. An array name is local to a program unit.

An array element is specified by the array name and a subscript. The form of an array element name is

a (s [,s]...)

where a is an array name, (s [,s]...)is a subscript, and s is a subscript expression.

For example, DATE(1,5) accesses the element in the first row, fifth column, of the DATE array.

The number of subscript expressions must be equal to the number of dimensions in the array declarator for the array name.

An array element can be any of the valid Fortran data types. All array elements must be the same data type. Specify the data type explicitly using a type statement or implicitly using the first character of the array name. See Chapter 1, “Fortran Elements and Concepts” for details about data types.

Reference a different array element by changing the subscript value of the array element name.

Array Declarators

An array declarator specifies a symbolic name for the array, the number of dimensions in the array, and the size and bounds of each dimension. Only one array declarator for an array name is allowed in a program unit. The array declarator can appear in a DIMENSION statement, a type statement, or a COMMON statement but not in more than one of these.

An array declarator has the form

a (d[,d]...)

where a is a symbolic name of the array and d is a dimension declarator of the form [d1:]d2. d1 is a lower-dimension bound that must be a numeric expression. d2 is an upper-dimension bound that must be a numeric expression or an asterisk (*). Specify an asterisk only if d2 is part of the last dimension declarator (see below).

If d1 or d2 is not of type integer, it is converted to integer values; any fractional part is truncated.

An array declarator can have a dummy argument as an array name and, therefore, be a dummy array declarator. An array declarator can be one of three types: a constant array declarator, an adjustable array declarator, or an assumed-size array declarator.

Each of the dimension bounds in a constant array declarator is a numeric constant expression. An adjustable array declarator is a dummy array declarator that contains one or more dimension bounds that are integer expressions but not constant integer expressions. An assumed-size array declarator is a dummy array declarator that has integer expressions for all dimension bounds, except that the upper dimension bound, d2, of the last dimension is an asterisk (*).

A dimension-bound expression cannot contain a function or array element name reference.

Value of Dimension Bounds

The lower-dimension bound, d1, and the upper-dimension bound, d2, can have positive, negative, or zero values. The value of the upper-dimension bound, d2, must be greater than or equal to that of the lower-dimension bound, d1.

If a lower-dimension bound is not specified, its value is assumed to be one (1). The upper-dimension bound of an asterisk (*) is always greater than or equal to the lower dimension bound.

The size of a dimension that does not have an asterisk (*) as its upper bound has the value (d1 - d2) +1.

The size of a dimension that has an asterisk (*) as its upper bound is not specified.

Array Size

The size of an array is exactly equal to the number of elements contained by the array. Therefore, the size of an array equals the product of the dimensions of the array. For constant and adjustable arrays, the size is straightforward. For assumed-size dummy arrays, however, the size depends on the actual argument corresponding to the dummy array. There are three cases:

  • If the actual argument is a non-character array name, the size of the assumed-size array equals the size of the actual argument array.

  • If the actual argument is a non-character array element name with a subscript value of j in an array of size x, the size of the assumed-size array equals x - j + 1.

  • If the actual argument is either a character array name, a character array element name, or a character array element substring name, the array begins at character storage unit t of an array containing a total of c character storage units; the size of the assumed-size array equals:

    INT((c- t + 1)/ ln)

    where ln is the length of an element of the dummy array.


Note: Given an assumed-size dummy array with n dimensions, the product of the sizes of the first n - 1 dimensions must not be greater than the size of the array (the size of the array is determined as described previously).


Storage and Element Ordering

Storage for an array is allocated in the program unit in which it is declared, except in subprograms where the array name is specified as a dummy argument. The former declaration is called an actual array declaration. The declaration of an array in a subprogram where the array name is a dummy argument is called a dummy array declaration.

The elements of an array are ordered in sequence and stored in column order. This means that the left most subscript varies first, as compared to row order, in which the right most subscript varies first. The first element of the array has a subscript value of one; the second element has a subscript value of two; and so on. The last element has a subscript value equal to the size of the array.

Consider the following statement that declares an array with an INTEGER type statement:

INTEGER t(2,3)

Figure 2-1 shows the ordering of elements of this array.

Figure 2-1. Order of Array Elements

Order of Array Elements

Subscripts

The subscript describes the position of the element in an array and allows that array element to be defined or referenced. The form of a subscript is

(s[,s]...)

where s is a subscript expression. The term subscript includes the parentheses that delimit the list of subscript expressions.

A subscript expression must be a numeric expression and can contain array element references and function references. However, it cannot contain any function references that affect other subscript expressions in the same subscript.

A non-integer character can be specified for subscript expression. If specified, the non-integer character is converted to an integer before use; fractional portions remaining after conversion are truncated.

If a subscript expression is not of type integer, it is converted to integer values; any fractional part is truncated.

Because an array is stored as a sequence in memory, the values of the subscript expressions must be combined into a single value that is used as the offset into the sequence in memory. That single value is called the subscript value.

The subscript value determines which element of the array is accessed. The subscript value is calculated from the values of all the subscript expressions and the declared dimensions of the array:

Table 2-13. Determining Subscript Values

n

Dimension Declarator

Subscript

Subscript Value

1

(j1:k1)

(s1)

1 + (s1 - j1)

2

(j1:k1, j2:k2)

(s1, s2)

1 + (s1 - j1) + (s2 - j2)*d1

3

(j1:k1, j2:k2, j3:k3)

(s1, s2, s3)

1 + (s1-j1) + (s2-j2) * d1 + (s3-j3) * d2 * d1

n

(j1:k1, ....jn:kn)

(s1, ...sn)

1 + (s1 - j1) + (s2 - j2)*d1 + (s3-j3)*d1*d2 +

 

 

 

... + (sn - jn) * dn-1*dn-2*d1

    

The subscript value and the subscript expression value are not necessarily the same, even for a one-dimensional array. For example,

DIMENSION X(10,10),Y(-1:8)
Y(2) = X(1,2) 

Y(2) identifies the fourth element of array Y, the subscript is (2) with a subscript value of four, and the subscript expression is 2 with a value of two. X(1,2) identifies the eleventh element of X, the subscript is (1,2) with a subscript value of eleven, and the subscript expressions are 1 and 2 with the values of one and two, respectively.