Problem:
Is this working correctly
WS-UNSIGNED PIC 9(15) COMP-5 VALUE ZERO.
WS-SIGNED PIC S9(15) COMP-5 VALUE ZERO.
WS-BYTES PIC X(20) VALUE '-1380985813'
MOVE FUNCTION NUMVAL(WS-BYTES) TO WS-UNSIGNED
MOVE FUNCTION NUMVAL(WS-BYTES) TO WS-SIGNED
After the above operation was performed:
WS-UNSIGNED = 2057592656942123
WS-SIGNED = -0000001380985813
Can this be explained?
Resolution:
The explanation has to do with the definition of the compiler directive comp-5.
COMP-5 compiler directive by default is set to COMP-5"2"
COMP-5(2) says that negative numbers are stored in an unsigned COMP-5 item in 2's complement form. This is exactly what is happening.
If you want the sign preserved then you need to store the value in a signed data item.
If you want the absolute value then use ABS intrinsic functions in conjunction with NUMVAL
MOVE FUNCTION ABS(FUNCTION NUMVAL(WS-BYTES)) TO WS-UNSIGNED MOVE
If you change the COMP-5 directive to COMP-5"1" then the results will show the correct decimal value without the leading minus sign.
from the on-line docs on COMP-5 compiler directive:
COMP-5
Specifies whether the sign is to be dropped when a value is stored in an unsigned COMP-5 data item.
Syntax:
>>-.---.--COMP-5--"integer"----------------><
-/-
Parameters:
integer Must be one of:
1 Behavior as in earlier versions of this Compiler. The sign is dropped.
2 The sign is not dropped. Negative numbers are stored in two's complement form, so that, except for their byte-order being machine dependent, unsigned COMP-5 items behave like COMP-X. This results in highly efficient arithmetic on unsigned COMP-5 items.