Getting Started Documentation Glish Learn More Programming Contact Us
Version 1.9 Build 1556
News FAQ
Search Home


next up previous contents index
Next: Strings Up: Values, Types, and Constants Previous: Overview

Subsections



Numeric Types

The types boolean, byte, short, integer, float, and double should be familiar to most programmers as Boolean, unsigned char (integer in the range 0 to 255), short integer, integer, single-precision floating-point, and double-precision floating-point types.

The types complex and dcomplex correspond to single-precision floating-point complex and double-precision floating-point complex numbers. In Glish these types are represented as a pair of floating-point numbers. One number is designated as the real portion and the other is designated as the imaginary portion of the complex number. In the case of complex, each of the numbers are single-precision, and in the case of dcomplex, each of the numbers are double-precision. The two functions for accessing the components of these numbers are real which returns the real portion of a complex value, and imag which returns the imaginary portion of a complex value. These functions work on vectors of complex or dcomplex numbers. The length of the resultant vector is equal to the length of the vector argument.

These types are referred to collectively as numeric. Numeric types can be used in arithmetic and logical operations (see § 3.2.3-§ 3.2.4 below) as well as in comparisons (§ 3.2.5, page [*]). The maximum and minimum values for numeric types can be found by looking at system.limits.max and system.limits.min.


Numeric Constants

The two boolean constants T and F represent the values of ``true" and ``false", respectively.

The integer constants are just strings of digits, optionally preceded by a + or - sign: 1234, -42, and +5 for example.

You write floating-point constants in the usual ways, as a string of digits with perhaps a decimal point and perhaps a scale-factor written in scientific notation. Optional + or - signs may be given before the digits or before the scientific notation exponent. Examples are -1234., 3.14159, and .003e-23. All floating-point constants are of type double.

The dcomplex constants are written as a floating-point number followed by a + or - sign (this part is optional), followed by a second floating-point number which must be immediately, i.e. no whitespace, followed by an i. All complex constants are of type dcomplex. All of the following are valid:

    23.12-7.2i
    2.31+.003e-23i
    2.3i
    34 + 2i
When no extra white space exists within the complex constant, the number is translated directly to a complex constant, otherwise an addition (of two complex numbers) is performed. So in 34 + 2i, 34 is converted to a dcomplex value, and this value is added to 2i. Omitting the imaginary floating point number results in a reference to the variable i, if it happens to exist. If the i does not immediately follow the imaginary portion, as in 4 - 3 i, a runtime error results.


Mixing Numeric Types

You can freely intermix numeric types in expressions. When intermixed, values are promoted to the ``highest" type in the expression.

In general, this promotion follows a simple hierarchy:

    (highest)

    dcomplex
    complex (*)
    double  (*)
    float
    integer
    short
    byte
    boolean

    (lowest)
where types are promoted upward (e.g., mixing a byte value and a float value will promote to float, since float appears higher in the list). The sole exception to this linear hierarchy is when mixing double values with complex values; these are always promoted to dcomplex, to preserve the precision of the double value. For example,
    a := [T, F, T]
    a[2] := 3.0
    a[3] := as_complex(-2+1i)
    b := [1, 2, 3]
    b[2] := 4-3i
a's type is initially boolean, becomes double with the first assignment, and finally becomes dcomplex after the last assignment to a. Thus a ends up as a dcomplex despite the fact that a complex is assigned to it because a's type was double at the time of the assignment. In this same example b starts out as integer, but after the assignment, ends up dcomplex because complex constants are of type dcomplex.

When converting boolean values to other numeric values, ``true" is promoted to 1 and false to 0. Thus the expression 5 + T yields the integer value 6 and 3.2 * 4 yields the double value 12.8. The type conversion functions can be used to prevent type promotion. For example,

    as_integer(3.2) * 4
yields the integer value 12. (See § 10.2, page [*], for specifics on how each as_X function works.) You can also use floor and ceiling to convert floating point values to integers (see § 10.2.2, page [*]).


Arithmetic Operators

Glish supports +, -, *, /, %, and ^ for doing arithmetic. The first four have their usual meaning. They evaluate their operands after converting them to the higher type of the two and return a result of that type. Division converts the operands to double and yields a double value, unless a complex or dcomplex value is involved. If a complex value is one of the division operands, the result is a dcomplex value. + and - can also be used as unary operators. For example,

    -[3, 5]
yields
    [-3, -5]

To compute a modulus use % the same way as in the C language. It evaluates its operands as integer and returns an integer result.

To perform exponentiation use ^. It evaluates its operands as double values or dcomplex values if a complex number is involved and returns a double or dcomplex value of the same type as the evaluated operands. Thus

    3^5
returns the double value 243.0, but
    2+3i ^ 2
returns the dcomplex value -5+12i.

As discussed above in § 3.1.4, page [*], the arithmetic operators all operate element-by-element when given two equal-sized vectors. For example,

    a := [1, 3, 5]
    b := a * 2:4
assigns to b
    [2, 9, 20]
If one of the vectors is a scalar then the scalar is paired with each element in turn:
    1:5 ^ 2
yields the double vector
    [1.0, 4.0, 9.0, 16.0, 25.0]
Operations on vectors of different sizes, such as
    1:5 ^ [2, 3]
result in run-time errors.

Binary + and - have the lowest precedence, *, /, and % have equal and next highest precedence, and ^ has highest precedence of the binary operators. The precedence of ^ is just below that of the : operator discussed in § 3.1.4, page [*]. The unary + and - operators have precedence just above :. (See § 4.14, page [*], for a table of the precedence of all Glish operators.)

All arithmetic operators associate from left-to-right except for ^, which associates from right-to-left.

Finally, a number of arithmetic functions are also available, most of which operate element-by-element on their operands. (See § 10.3, page [*], for descriptions.)


Logical Operators

Glish supports three logical operators: &, |, and !, are Boolean ``and", ``or", and ``not", respectively.

The &, | operators require boolean operands, and other numeric types are not automatically converted to boolean in this case. As with the arithmetic operators, these operate on multi-element vectors element by element. For example,

    [T, F, F, T] & [F, F, T, T]
yields
    [F, F, F, T]
while
    [T, F, F, T] | T
yields
    [T, T, T, T]
(See § 4.5, page [*], for a discussion of the related && and || operators.)

The unary ! operator negates its operand. It first converts any numeric operand to boolean by treating a value of 0 (zero) as false and any other value as true. For example,

    ! [T, F, F, T]
yields
    [F, T, T, F]
and
    ! 5e-238
yields false.

The logical operators are left-associative. The | operator has precedence just below &, which in turn is just below that of the comparison operators (see § 3.2.5, page [*]). The ! operator has very high precedence, the same as unary + and -. (See § 3.2.3 and § 4.14.)

§ 10.3, page [*], discusses the predefined functions for operating on logical values.


Comparison Operators

Glish provides the usual comparison operators: ==, !=, <, <=, >, and >=. Each takes two operands and converts them to the higher of the two types (see § 3.2.2, page [*]). They return a boolean vector corresponding to the element-by-element comparison of the operands. For example,

    3 < 3.000001
yields true, and
    1:4 == [3,2,3,2]
yields
    [F, T, T, F]
The boolean value true is considered greater than false. For example,
    F < T
yields true.

Comparisons are also defined for complex and dcomplex numbers. The result of a comparison operator applied to complex numbers is the result of the comparison applied to the real portion of those numbers. If, however, the real components of the complex numbers are equal, the result of the comparison is the comparison operator applied to the imaginary portion of the numbers. So the result of,

    3-2i < 4+7i
is true because, comparing the real components, 3 is less than 4. However,
    3+2i < 3-1i
is false because now you're comparing the imaginary components due to the fact the real components are equal, 2 is not less than -1.

You can also use the == and != operators to compare non-numeric values. (See § 4.4, page [*] for details.)

The comparison operators are all non-associative and have equal precedence, just below that of binary + and - (see § 3.2.3, page [*]) and just above that of the logical & operator (see § 3.2.4, page [*]). For a general discussion of precedence see § 4.14, page [*].

Indexing With Numeric Types

You can use numeric values to index vectors in two different ways. The boolean values serve as masks for picking out vector elements when some condition is true, and non-boolean values (converted to integer) serve as indices for specifying a particular set of elements in a vector. For a discussion of different ways of indexing see § 3.6, page [*].


next up previous contents index
Next: Strings Up: Values, Types, and Constants Previous: Overview   Contents   Index
Please send questions or comments about AIPS++ to aips2-request@nrao.edu.
Copyright © 1995-2000 Associated Universities Inc., Washington, D.C.

Return to AIPS++ Home Page
2006-10-15