## RPG Tutorial: Expanded discussion of selected calculation operations

Arithmetic Operations

Fields and literals used in arithmetic operations must always be numeric.  Decimal point alignment is automatically handled by the RPG compiler so that the addition, say, of two fields -- 567.94 and 3.4578 -- will result in the correct sum: 571.3978.  The number of positions to the right of the decimal in the result field is determined by an entry in column 52 of the calculation specification.  The maximum field length for an arithmetic operation is 15 digits and the result field, after automatic decimal alignment is taken into account, also must not exceed 15 digits.  In many programming languages, an arithmetic calculation may result in an overflow condition.  This comes about when the data field which is to contain the answer has fewer positions than the number of positions in the answer.  Consider, for example, adding two four-position fields together and causing the sum (result) to be stored in a four-position field.  If the first field contains the value 5923 and the second field contains 4670, the answer, 10593, clearly has more digits than can be represented in a four-position result field.  In this case, an arithmetic overflow has occurred.  The result field will contain 0593 and the 1 in the ten thousands position will be lost.  Most language compilers generate overflow indicators that will signal when this type of overflow occurs and the program can test the indicator and take appropriate action.  This is not possible in RPG.  Overflows are not detectable by the object program and, if resulting fields are not specified with sufficient length, erroneous results may occur.

This operation causes the contents of the data field named in factor 2 to be added to the data field named in factor 1.  The sum is stored in the data field named in the result.   The number of digits to the right of the decimal point in the result field must be specified in column 52.

This operation first sets the data field named in the result of the specification statement to zero.  The contents of the data field named in factor 2 are then added to the result field.  Factor 1 is not used in this operation.  Factor 2 may contain a numeric literal rather than the name of a data field.

Subtract (SUB)

The contents of the data field named in factor 2 are subtracted from the contents of the data field named in factor 1, and the difference is placed in the data field named in the result of the specification statement.  The sign of the result will be derived using conventional algebraic rules.

Zero and Subtract (Z-SUB)

As with Z-ADD, this operation sets the data field named in the result portion of the specification statement to zero.  Then the data field named in factor 2 is subtracted from the data field named in the result.  This has the effect of placing a value in the result field that has the opposite sign from that in factor 2.  Factor 1 is not used in this operation.  Factor 2 may contain a numeric literal rather than the name of a data field.

“Half adjusting” is a term that refers to a method of rounding the results of calculations. Suppose, for example, that a program is to divide one three-digit value into a four-digit value and the result is to be rounded to four significant digits.  The answer, known as the quotient, might have any number of digits.  If the divisor were 035 and the dividend were 4671, the quotient would be 0133.462....  If we want to round this to four significant digits, we would write 0133.  If the digit in the tenths position had been five or greater, we would have written 0134.  When calculations are being performed by a computer, a way must be developed that will cause the computer to record the rounded value, 0134 in this case, rather than the 0133 which would result from simply dropping the low-order digits.  This can be done by adding the digit 5 one position to the right of the position containing the least significant digit of the answer. In our example, this would look like this:

0133.46 + .5 = 0133.96

Now, dropping the two digits to the right of the decimal point yields the value 0133 which is the correct rounded value given a tenths position digit of less than 5.  If the result of a similar calculation were 1198.67, a similar rounding technique would result in the following:

1198.67 + .5 = 1199.17

Dropping the two unwanted digits yields, again, the correct rounded value of 1199.  Half adjusting is a technique that adds the digit 5 to the position immediately to the right of the least significant digit desired in a result data field.  In RPG programming, half adjusting of result fields is caused by entering the letter H in column 53 of the specification containing the arithmetic calculation operation to be half adjusted.

Multiply (MULT)

This operation multiplies the contents of the data field or literal specified in factor 2 by the contents of the data field or literal specified in factor 1.  The result is placed in the data field named in the result.  The sign of the result will be derived using conventional algebraic rules.  The number of digits required to the right of the decimal point is entered in column 52 and the total length of the result field is specified in columns 49-51.

Divide (DIV)

The contents of the data field named in factor 1 or the literal specified in factor 1 is divided by the data field or literal specified in factor 2.  Since division by zero is not defined as a mathematical operation, the data field specified in factor 2 or a literal entered there may not have a value of zero.  In divide operations, the lengths of the data fields or literals specified in factors 1 and 2 must adhere to specific rules or invalid results will be obtained. These length rules must be followed:

L1 + (D2 - D1 + DR) =< 15
L2 - (D2 - D1 + DR) =< 15

where:

L1 represents the length of the data field specified in factor 1;
L2 represents the length of the data field specified in factor 2;
D1 represents the number of digits to the right of the decimal point in factor 1;
D2 represents the number of digits to the right of the decimal point in factor 2;
DR represents the number of digits to the right of the decimal point in the result field.

If half adjusting is specified, the length formula involving factor 1 must satisfy this:

L1 + (D2 - D1 + DR) =< 14.

The process of division often leaves a remainder.  The remainder is available to the object program immediately after the execution of the divide operation.  Thereafter, it is lost.  If the object module is to make use of the remainder, a Move Remainder operation must follow immediately after the divide operation.

Move Remainder (MVR)

This operation places the remainder, resulting from a divide operation, in the data field specified in the result columns of the specification statement.  The length of the result field specified in a MVR operation must be equal either to the number of positions to the right of the decimal point in the dividend (D1) or to the sum of the number of positions to the right of the decimal point in the divisor and the quotient (D2 + DR), whichever is greater.  Half adjusting should not be performed on a quotient if the remainder is to be saved by a MVR operation.  Resulting indicators may be specified for MVR operations using columns 54-59.

MOVE OPERATIONS

A move operation is one in which data are moved from one data field to another without arithmetic operations being performed.  A move operation causes data stored in the data field named in factor 2 to be moved to the data field named in the result of the specification statement.  The data in the field named in factor 2 are not changed.  Thus, after a move operation, some or all of the data in the factor 2 field are stored in two fields, the factor 2 field and the result field.  One use of move operations causes the data field moved to be changed from alphanumeric to numeric or vice versa.

If an alphanumeric field is moved to a numeric result field (decimal positions specified in column 52), the alphanumeric data are converted to numeric form.  In internal storage, this amounts to converting from character mode to packed decimal.

The reverse of this process occurs when a numeric field is moved to an alphanumeric result field (decimal positions are not specified by leaving column 52 blank).

Move (MOVE)

This operation causes characters to be moved from the data field specified in factor 2 to the data field specified in the result.  Movement may be visualized as from the right-most position of the sending field (factor 2) to the right-most position of the receiving field (result).  Characters move one at a time, from right to left.  If the receiving field is longer than the sending field, the high-order or left-most positions of the receiving field, which are not replaced by characters from the sending field, are left undisturbed.  If the receiving field is shorter than the sending field, the excess high-order positions of the sending field are not moved.  Factor 1 is not used in MOVE operations.

Move Left (MOVEL)

The MOVEL operation transfers data in a manner just the opposite of the MOVE operation.  Characters are moved from left to right from the data field specified in factor 2 to the data field specified in the result of the specification statement.  If the factor 2 data field is longer than the result data field, the excess low-order or right-most positions of the factor 2 field are not moved.  If the result data field is longer than the field specified in factor 2, the low-order positions of the result field, which are not replaced by characters from the factor 2 data field, are left undisturbed.  If the result data field is numeric (a digit is placed in column 52 of the specification), the result field will contain the sign of the factor 2 field unless the factor 2 field is shorter than the result field in which case the sign of the result field will be the same as it was before the move.  Factor 1 is not used in MOVEL operations.

Compare (COMP)

This operation causes the contents of the data field named in factor 1 (or the literal specified) to be compared against the data field or literal specified in factor 2.  Resulting indicators to be turned on according to whether the factor 1 data were higher than, lower than, or equal to the factor 2 data may be entered in columns 54-59.   The indicator specified in columns 54-55 (High, 1 > 2), for example, will be turned on by the object module if the factor 1 data field (or literal) is greater than the factor 2 data field (or literal).  Similarly, the indicators specified in columns 56-57 (low, 1 < 2) and 58-59 (equal, 1 = 2) are turned on if the factor 1 data is less than or equal to the factor 2 data respectively.

In performing compare operations, the RPG compiler generates object code to align the data fields to be compared according to whether they are alphanumeric or numeric.  If alphanumeric fields of unequal length are compared, the fields are aligned to their left-most characters and unused positions of the shorter field are filled with blanks.  The blanks filled into the short field will then be compared with the characters in the low-order positions of the long field.  If numeric fields of unequal length are compared, the fields are aligned according to their decimal point, and missing digits are filled with zeros.  As a result, comparison of unequal numeric fields will yield a valid comparison.   Alphanumeric fields of equal length to be compared must not exceed 256 characters each.  If alphanumeric fields are unequal in length, they must not exceed 200 characters each.  In RPG, numeric comparisons are always made on an algebraic basis, that is, the sign of the data is taken into account.  Thus, the value -89 is not equal to, but is less than 89.

Branch (GOTO) and (TAG)

Operations, as specified in the calculation specifications, are performed at either detail time or total time in the sequence they occur in the source program.  Occasionally, it may be desirable to branch to other parts of the object program rather than proceeding through the sequential execution of calculation operations.  When this is the case, the GOTO specification may be used.  This entry specifies the next operation to be performed.  This operation (to which branching is to take place) must be identified by a special label called a tag.  A tag is a name that the programmer assigns to the specification statement to which he wants the object program to branch.  A tag operation is one which assigns a label to an instruction. The operation code TAG is entered in columns 28-30, and the label to be associated with the operation on the following line is entered in factor 1.  Branching operations may be forward or backward, however, branching may not be performed from a detail routine into a total routine or vice versa.

INDICATOR CONTROL OPERATIONS

Indicators are used to control the various operations to be performed by the object program.  Three types of indicators are used in RPG specifications.  These include the resulting indicators, which may be turned on to identify types of input records and status of data fields; control level indicators that are used to cause appropriate action to be taken in the event of a control break; halt indicators that are used to cause the object module to terminate the program that can be specified to be turned on under certain circumstances on the calculation and input specification sheets.  In addition to being turned on as the result of a calculation or other processing specification, these indicators may also be turned on and off by special specifications for that purpose.  The specifications that do this are the SETON and SETOF operations.

Set On (SETON)

This operation may be used to turn on any indicator except the LO indicator and 00 indicator, which are always on throughout the program.  The indicators to be turned on are specified in columns 54-59 which are normally used for entry of resulting indicators for specifications other than SETON or SETOF.  As many as three indicators may be turned on in one SETON specification.  Whether or not a SETON operation is to be performed may be controlled by indicators entered, as with all calculation specifications, in columns 7-17.

Set Off (SETOF)

This operation may be used to turn off any indicator except the LO indicator and the 00 indicator, which are always on throughout the program.  The indicators to be turned off are specified in columns 54-59 which are normally used for entry of resulting indicators for specifications other than SETON or SETOF.  As many as three indicators may be turned off in one SETOF specification.  Whether or not a SETOF operation is to be performed may be controlled by indicators entered, as with all calculation specifications, in columns 7-17. 