This section covers the basic OPL constructions that can be used within a procedure. It describes the basic ways in which programs can deal with data, store and retrieve it, manipulate it and combine it.
See also: Control structures, Commands.
Section Contents
Before using a value, you must decide what sort of information you need to represent, and to some extent what you need to do with the data. There are different types of value for different tasks and uses.
Each value in an OPL program has a type associated with it. If you try to use the wrong type of value in a place where a particular type of variable is expected, an error message will be displayed when you try to translate your program.
The numbers and strings in quote marks written in an OPL program are sometimes called literals. In practice, you will use literal values without thinking about them. For example:
0.32 |
Floating-point number. |
569 |
Integer. |
32768 |
Long integer. |
$2b |
Integer, specified in hexadecimal. |
"hello" |
String. |
You can only use these values in a statement such as print "hello world" so this section will use the print command when discussing values.
OPL can represent values of various kinds. Each value has an associated type.
Before using a value, decide what information you need to represent. There are different types of variables for different sorts of values. If you try to give the wrong type of value to a variable, an error message will be displayed.
Integers can only be used for numbers in the range -32768 to +32767.
Long integers can handle whole numbers in the range -2147483648 to +2147483647. If you may have to handle numbers outside normal integer range, use the long integer representation.
Floating-point numbers can represent numbers from
If you know that at some stage in your program your variable will have to handle non-whole numbers, like 1.2, use a floating-point, not an integer variable. Otherwise you may get unpredictable results. (Theres more about this later in this topic.)
For very large whole numbers outside long integer range you should also use floating-point variables.
When assigning numbers to a variable, you should ensure the variable is of the right type. You may get unpredictable results or translation errors if a variable is not of the right type for the value it is to store (see below).
Besides writing simple decimal numbers as above, you can also write numbers in hexadecimal, or use exponential notation.
Integers specified in hexadecimal must be preceded by a $ and long hex integers by a &. For example, $f or &80000000. This is explained under the HEX$ entry in the Keyword Reference section.
Exponential notation may be useful for very large or very small numbers. Use E (capital or lower case) to mean times ten to the power of for example, 3.14E7 is 3.14 x 107 (31400000), while 1E-9 is 1 x 10-9 (0.000000001).
It is possible to use the full available range of 64-bit floating-point values, i.e. all real numbers with absolute values in the range
Constants for the maximum and minimum values of all variable types are given in Const.oph
. See const.oph for more on this.
With SETFLAGS KTwoDigitExponent& in effect, floating-point variables can only represent numbers as big as
For text Are you sure?, 54th, etc. use a string variable.
To write a string, write the string in double quotes:
print "some text"
A string can only be written on one line; it may contain no return characters. If you need to write a double quote character in a string, use "". OPL understands doubled "s in a string as single "s:
print """This deck contains no twos"", Tom deduced."
Section Contents
OPL can store values and use them later by declaring that a name represents a particular value. This can be done in two ways, either by a variable or by a constant. Variables are used to store values which may change, and constants store fixed values.
Most procedures begin by declaring (creating) variables:
LOCAL x,y,z
LOCAL is the keyword telling OPL to create variables, with the names which follow - here x, y and z separated by commas. These variables initially have the value 0.
The statement LOCAL x,y,z declares three variables called x, y and z. OPL will recognise these names whenever you use them in this procedure. If you used them in another procedure, they wouldnt be recognised; the variables are local to the procedure in which they are declared.
Any variables you wish to use must be declared at the start of a procedure.
Variables can also be declared GLOBAL at the start of a procedure if you want them to be recognised by other procedures. See GLOBAL under Keyword Reference for more on this.
Two variables cannot have the same name. For example, it is not possible to write:
PROC badProcedure: LOCAL x,y,z GLOBAL v,w,x REM duplicate "x" value ENDP
This will display a Duplicate name error when you try to translate it.
To make it easier to write your programs, and understand them when you read through them at a later date, give your main variables names which describe the values they hold. For example, in a procedure which calculates fuel efficiency, you might use variables named speed and distance.
All variable names:
The $, & and % symbols (see Variable types, below) are included in the 32 characters allowed in variable names, so V2345678901234567890123456789012% is too long to be a valid variable name, but V234567890123456789012345678901% is acceptable.
When variables are declared, they automatically get a default value. See Initial values.
The types a variable can have correspond to the types of value OPL can represent (see Types of value, above)
Simple numbers and strings are called scalar values. You give the type of a variable by appending a type character onto the end of the variable name:
Type character |
Variable type |
Example declaration |
(nothing) |
Floating-point. |
LOCAL aFloating |
% |
Integer. |
LOCAL anInteger% |
& |
Long integer. |
LOCAL aLong& |
$ |
String. |
LOCAL aString$ |
You may want a group of variables, for example to store lists of values. Instead of having to declare separate variables a, b, c, d and e, you can declare array variables a(1) to a(5) in one go like this:
LOCAL a%(5) |
Array of integer variables. |
LOCAL a(5) |
Array of floating-point variables. |
LOCAL a$(5,8) |
Array of string variables (note the second number). |
LOCAL a&(5) |
Array of long integers. |
The number in brackets is the number of elements in the array. So LOCAL a%(5) creates five integer variables: a%(1), a%(2), a%(3), a%(4) and a%(5).
With strings, the second number in the brackets specifies the maximum length of the strings. All the elements in the string array have the same capacity for example, LOCAL ID$(5,10) allocates memory space for five strings, each up to 10 characters in length.
OPL does not support two-dimensional arrays.
However, the cardinal rule is still to use the right kind of variable for the values you want to store. If a number needs to represent non-integer quantities, use a floating-point variable to store it, and if it needs to represent large numbers, use a long integer or a floating-point number as appropriate.
When a variable is declared, it automatically has some default value. For numeric values, the initial value is zero. For strings, the initial value is the empty string (written "").
Values can be assigned to a variable using an assignment statement. This is the variable name, an equals sign, and the value you want to assign to the variable. Examples are:
a%=42 profit=378.373721 greeting$="Good day!" bignum&=65535+2001-(42*3)
In assignment statements, the variable assigned to can be used in the expression to the right of the equals sign. Expressions are covered below.
z%=z%+1 |
makes the value of z% one greater than its current value |
x%=(x%/4)+y% |
makes the value of x% a quarter of its current value, plus the value of y% |
A variable name can be used anywhere youd normally use a variable of the appropriate type. For example:
PROC test1: LOCAL i% i% = 42 PRINT 42+7 PRINT i%+7 GET REM Wait for a keypress ENDP
This example prints 49 twice, because i% was assigned the value 42.
Constants are essentially variables whose values can never change. They are used exactly like variables (see Using variables Getting a variables value, above), but their declaration is different.
Using constants allows you to assign a name to a value so it may be used throughout the module. If you need to use a particular value several times in your program, it is easier to define it as a constant and use its name rather than spelling it out in full every time you need to use it. Also, if the value you need to use changes during your programs development, it is far easier to change a single value at the top of a module than it is to change every occurrence of a value in the program.
Constants can be shared between modules, and there are several standard OPL values defined in Const.oph
. See Including header files for more on how to use this.
By convention, all constants are named with a leading K to distinguish them from variables.
Constants are declared with the CONST keyword. Because their value never changes, constants must be assigned a value where they are declared:
CONST KMinimumTemp%=-237
Constants must be declared outside procedures. You will get a translation error if you try to declare a constant inside a procedure.
The names of constants must not clash with those of variables declared with LOCAL or GLOBAL. Its usual to add a K prefix to the constant name. This helps avoid name clashes, and is also a useful reminder that you cant change the names value when you use it.
Section Contents
Expressions are combinations of numbers, variables, and functions that the interpreter can use as a value. An example of an OPL statement using an expression is:
print 42+(2*3)
The value of the expression 42+(2*3) is 48, so the statement prints 48 to the text display.
Expressions can be built from other expressions (sub-expressions) as well as values: notice that in the example above, (2*3) is a sub-expression. Expressions can be as complex as you like, although its a good idea to keep things reasonably simple so you can understand them later.
Expressions can be used anywhere OPL expects a value. Types of expression include operations on values, and function calls.
For example:
z=x+y/2 |
gives z the value of x plus the value of y/2. |
z=x*y+34.78 |
gives z the value of x times y, plus 34.78. |
z=x+COS(y) |
gives z the value of x plus the cosine of y. |
COS(y) in the example above is a function call see Values from functions below.
You can use these operators:
+ |
Plus. |
x%+13 |
- |
Minus (or make negative). |
-70-32.8 |
/ |
Divide. |
9/3 |
* |
Multiply. |
9*5 |
** |
Raise to a power. |
2**8 |
% |
Percentage. |
17.5% |
Operators have the same precedence as in the Calc application. For example, 3+51.3/8 is treated as 3+(51.3/8), not (3+51.3)/8. For more information on operators and precedence, see Operators and logical expressions.
There are two kinds of keyword commands and functions:
GET (as used above) is, in fact, a function; it waits for you to press a key on the keyboard, and then returns a value which identifies the key which was pressed. In previous example programs, the value returned by GET was ignored, as GET was being used to provide a pause while you read the screen. This is a common use of the GET function.
The number returned by GET will always be a small whole number, so you might store it away in an integer variable, like this:
a%=GET
There is more about the GET function later in this topic.
a%=COS(b)
COS is another OPL function. Unlike the GET function, COS requires a value or variable to work with. As you can see, you put this in brackets after the function name. Values you give to functions in this way are called arguments to the function. There is more information about arguments in Commands.
When calculating an expression, OPL uses the simplest arithmetic possible for the numbers involved. If all of the numbers are integers, integer arithmetic is used; if one is outside integer range, but within long integer range, then long integer arithmetic is used; if any of the numbers are not whole numbers, or are outside long integer range, floating-point arithmetic is used.
This has the benefit of maximising speed, but you must beware of calculations going out of the range of the type of arithmetic used. For example, in X=200*300 both 200 and 300 are integers, so integer arithmetic is used for speed (even though X is a floating-point variable). However, the result, 60000, cannot be calculated because it is outside integer range (32767 to -32768), so an Overflow error is produced.
You can get around this by using the INT function, which turns an integer into a long integer, without changing its value. If you rewrite the previous example as X=INT(200)*300, OPL has to use long integer arithmetic, and can therefore give the correct result (60000). (If you understand hexadecimal numbers, you can instead write one of the numbers as a hexadecimal long integer, e.g. 200 would become &C8.)
Integer arithmetic uses whole numbers only. For example, if y% is 7 and x% is 4, y%/x% gives 1. However, you can use the INTF function to convert an integer or long integer into a floating-point number, forcing floating-point arithmetic to be used for example, INTF(y%)/x% gives 1.75.
This rule applies to each part of an expression e.g. 1.0+2/4 works out as 1.0+0 (=1.0), while 1+2.0/4 works out as 1+0.5 (=1.5).
If one of the integers in an all-integer calculation is a constant, you can instead write it as a floating-point number. 7/4 gives 1, but 7/4.0 gives 1.75.
If a$ is "down" and b$ is "wind", then the statement c$=a$+b$ means c$ becomes "downwind".
Alternatively, you could give c$ the same value with the statement c$="down"+"wind".
When adding strings together, the result must not be longer than the maximum length you declared e.g. if you declared LOCAL a$(5) then a$="first"+"second" would cause a String is too long error to be displayed.
Most operators do not work on strings. To cut up strings, use string functions like MID$, LEFT$ and RIGHT$, explained in the Keyword Reference section. You need these functions to extract even a single character you cannot, for example, refer to the fourth character in a$ as a$(4).