Problem:
In some Unix platforms the following example code gives unexpected results (different from 0).
01 WK-NUMER-12 PIC 9(12).
01 WK-QUOTIENT-06 PIC 9(06).
01 WK-REMAINDER PIC 9(02).
01 WK-CHECK PIC 9(01).
PROCEDURE DIVISION.
MOVE 114600120320 TO WK-NUMER-12.
MOVE 0 TO WK-QUOTIENT-06 WK-REMAINDER.
DIVIDE WK-NUMER-12 BY 7
GIVING WK-QUOTIENT-06 REMAINDER WK-REMAINDER.
IF WK-REMAINDER = ZEROS
THEN
MOVE 0 TO WK-CHECK
ELSE
SUBTRACT WK-REMAINDER FROM 7 GIVING WK-CHECK.
DISPLAY 'Check calculado: ' WK-CHECK-NJ.
Resolution:
The quotient arising from the divide is larger than the quotient target item, WK-QUOTIENT-06. Therefore a SIZE ERROR condition arises and the result is therefore undefined.
There might be cases were the IF statement appears not to be evaluated correctly. This would be due to the reminder having and undefined value that doesn't necessarily be a proper number. Any expression where the reminder is used from then on can not be trusted to be evaluated properly for this reason.
The appropriate solution would be to fix the code and make WK-QUOTIENT-06 big enough to hold any quotient, i.e. PIC 9(12).
Alternatively, the checker directive REMAINDER(2) can be used.
This is the definition of the REMAINDER directive in the manual:
"REMAINDER
Enables you to select how the remainder is calculated in a DIVIDE statement.
Syntax:
>>------REMAINDER---"integer"-----------><
Parameters:
integer Must be one of: 1 The Compiler uses the ANSI 85 algorithm.
2 The Compiler uses an algorithm employing a subsidiary quotient. This subsidiary quotient is signed and is of sufficient size to hold any valid value. All current IBM mainframe compilers use this non-standard algorithm.
Properties:
Default: REMAINDER"1"(Dialect )
Phase: Syntax check
$SET: Any