Getting Started | Documentation | Glish | Learn More | Programming | Contact Us |
Version 1.9 Build 1556 |
|
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
.
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 + 2iWhen 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.
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-3ia'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) * 4yields 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 ).
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^5returns the double value 243.0, but
2+3i ^ 2returns 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:4assigns 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 ^ 2yields 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.)
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] | Tyields
[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-238yields 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.
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.000001yields 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 < Tyields 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+7iis true because, comparing the real components, 3 is less than 4. However,
3+2i < 3-1iis 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 .
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 .