2.3.4.2.1. - Data Array Usage
Data arrays must be declared with the
array
key word.
One- and two-dimensional arrays are declared as:
[shared] [type] array var[cols] [shared] [type] array var[rows][cols]On platforms that support System V Interprocess Communication (IPC) calls, the shared keyword causes spec to place the array in shared memory (see below). The type keyword specifies the storage type of the array and may be one of
byte
, ubyte
, short
, ushort
, long
, ulong
, long64
, ulong64
, float
, double
or
string
. An initial
u
denotes the "unsigned" version of the data type.
The
short
and
ushort
types are 16-bit (two-byte) integers.
The
long
and
ulong
types are 32-bit (four-byte) integers.
The
long64
and
ulong64
types are 64-bit (eight-byte) integers.
The
float
type uses four bytes per element.
The
double
type uses eight bytes per element.
The default data type is
double
. The array name
var
is an ordinary spec variable name.
Arrays are global by default, although they may also be declared local
within statement blocks.
Unlike traditional spec associative arrays, which can store and be indexed by arbitrary strings or numbers, a data array is indexed by consecutive integers (starting from zero), and can hold only numbers, or in the case of
string
arrays, only strings.
Operations on these arrays can be performed on all elements of the array at once, or on one or more blocks of elements. Consider the following example:
array a[20] a = 2 a[3] = 3 a[10:19] = 4 a[2,4,6,10:15] = 5The first expression assigns the value 2 to all twenty elements of the array. The second expressions assigns 3 to one element. The third assign the value 4 to the tenth through last element. The final expression assigns the value 5 to the elements listed.
A negative number as an array index counts elements from the end of the array, with
a[-1]
referring to the last element of
a
. As per the usual conventions, the first index is row and the second is column. Note, however, spec considers arrays declared with one dimension to be a single row. For example,
array a[20]is a one-row, twenty-column array. Use
array a[20][1]to declare a 20-row, one-column array.
Also note well, all operations between two arrays are defined as element-by-element operations, not matrix operations, which are currently unimplemented in spec. In the following example:
array a[5][5], b[5][5], c[5][5] c = a * b
c[i][j]
is the product
a[i][j]
* b[i][j] for each
i
and
j
.
When two array operands have different dimensions the operations are performed on the elements that have dimensions in common. In the case:
array a[5][5], b[5], c[5][5] c = a * bonly the first row of
c
will have values assigned, since
b
only has one row.
The remaining elements of
c
are unchanged by the assignment.
Portions of the array can be accessed using the subarray syntax, which uses colons and commas, as in the following examples:
array a[10][10] a[1] # second row of a a[2:4][] # rows 2 to 4 a[][2:] # all rows, cols 2 to last a[1,3,5,7,9][3:7] # odd rows and cols 3 to 7
The elements of an array can be accessed in reverse order, as in:
a = x[-1:0]which will assign to a the reversed elements of
x
. Note, though, that presently, an assignment such as
x = x[-1:0]
will not work properly, as spec will not make a temporary copy
of the elements.
However,
x = x[-1:0]+0
will work.
The functions
fabs()
, int()
, cos()
, acos()
, sin()
, asin()
, tan()
, atan()
, exp()
, exp10()
, log()
, log10()
, pow()
and
sqrt()
can all take arrays as an argument.
The functions perform the operation on each element
of the array argument and return the results in an array
of the same dimension as the argument array.
The operations
<
, <=
, !=
, ==
, >
and
>=
can be used with array arguments.
The Boolean result (0 or 1)
will be assigned to each element of an array returned
as the result of the operation,
based on the element-by-element comparison of the operands.
The bit-wise operators
~
, |
, &
, >>
and
<<
can also be used with array operands.
Note, spec generally uses double-precision floating point for storing intermediate values and for mathematical operations. Double-precision floating point has only 52 bits for the significand (the remaining 12 bits are for sign and exponent). Thus, for most operations the 64-bit types will only maintain 52 bits of significance. (The 64-bit integer types were added in spec release 6.01.)