Problem:
Compiler directive HOSTARITHMETIC guarantees decimal truncation on arithmetic overflow when ON SIZE ERROR is not specified.
Does 9 1 = 0? If a data item can hold only one digit (PIC 9), and currently has the value 9, what should be the result of adding 1?
If the resulting value of an arithmetic expression is larger than the maximum value the target item can store, then a "size error" condition exists. If the ON SIZE ERROR clause is present, then no value is stored in the target, and the imperative statement(s) in the clause are executed.
If no ON SIZE ERROR clause is present, then the arithmetic results are undefined. This rule is documented in the ANSI standard, as well as in Micro Focus and IBM documentation. Thus, the result of the following code fragment is undefined, and it is a programmatic error to rely on any specific result:
01 num-ws pic 9 value 9.
add 1 to num-ws
In practice though, the IBM mainframe and Micro Focus .int code usually perform decimal truncation upon the intermediate result, causing the value to "roll over", so adding 1 to 9 results in the value 0 (similar to a "MOD" function).
Micro Focus received reports of COBOL programs being migrated from the mainframe, where the programs had an inherent dependency on this truncation or "roll over". The behavior of Micro Focus .int code already matched that of the mainframe in this area, but Micro Focus .gnt or .so or executable code did not.
Resolution:
Micro Focus implemented a new compiler directive: HOSTARITHMETIC. The directive was introduced in Server Express version 2.2 SP1 Fixpack 5 for Sun Solaris, and has since been implemented for all UNIX platforms in Server Express v4.0 SP1, and will be carried forward in subsequent releases. In all forms of compiled code (.int, .gnt, .so, and executable), this directive results in the following behavior:
If the result of an arithmetic operation (ADD, SUBTRACT, MULTIPLY, DIVIDE, COMPUTE) with no ON SIZE ERROR clause exceeds the maximum value the target item can hold, decimal truncation will be performed on the result, provided that:
-- The target item is a decimal type, that is DISPLAY, COMP-3 or COMP-6
-- None of the source items are floating-point items
-- No exponentiation or intrinsic functions are used in the calculation
-- Neither the composite of operands nor any intermediate result has more than 31 decimal digits
For example, the following code gives undefined results under ANSI standard rules, but defined results under the HOSTARITHMETIC compiler directive:
01 a pic 9 value 9.
01 b pic 9(2) value 16.
01 c pic 9(9).
01 d pic x(4) comp-5 value 100001.
add 1 to a *> gives 0
multiply b by b *> gives 56
compute c = d * d *> gives 200001