Search code examples
cobol

Decimal value turns into 00 when displayed in cobol


So i try to display a decimal number from some variable , lets say i have pic 9(13)v99 and i have a variable ws-amount with value 000000804793807 -> i expect the value when i display is 000000804793807(just ignore the '.' for separated decimal) But the reality is the spool display 000000804793800 . (i dont know how can the 07 turns into 00) ..

this is the code

Working storage section
01 WS-AMOUNT-15.                           
   05 WS-AMOUNT-13              PIC 9(13). 
   05 WS-DECIMAL-2              PIC V9(02).

01 WS-VALUE                     PIC 9(15).

PROCEDURE SECTION

MOVE 000000804793807 TO WS-VALUE
MOVE WS-VALUE(1:13)  TO WS-AMOUNT-13.
MOVE WS-VALUE(14:2)  TO WS-DECIMAL-2.
MOVE WS-AMOUNT-15             TO DA-PST-AMOUNT.   
//*TRY TO DISPLAY THE VALUE.  
DISPLAY 'AMT(1:13): ' WS-VALUE(1:13). 
DISPLAY 'AMT(14:2): ' WS-VALUE(14:2).           
DISPLAY 'WS-AMOUNT-13: ' WS-AMOUNT-13.              
DISPLAY 'WS-DECIMAL-2: ' WS-DECIMAL-2.              
DISPLAY 'WS-AMOUNT-15: ' WS-AMOUNT-15.               

Result

AMT(1:13): 0000008047938

AMT(14:2): 07

WS-AMOUNT-13: 0000008047938

WS-DECIMAL-2: 00

WS-AMOUNT-15: 000000804793800

is there anything wrong with my structure? i want the decimal of 07 remain in the ws-amount-15 , not 00 ..


Solution

  • The V is the implied decimal point which is taken into account for arithmetic and MOVE.

    I think your code has an undefined behavior because you MOVE an intermediate alphanumeric item, created by the reference-modification of a numeric variable, to a numeric field. My explanation uses the "assumption" that this is somehow still recognized as numeric variable:

    MOVE WS-VALUE(1:13)   TO WS-AMOUNT-13.
    

    equals to

    MOVE '0000008047938'  TO WS-AMOUNT-13.
    

    numeric conflict possibly solved by some kind of

    MOVE FUNCTION NUMVAL ('0000008047938') TO WS-AMOUNT-13.
    

    which is identical to

    MOVE 000000000000000000000000008047938 TO WS-AMOUNT-13.
    

    which gives the expected result (everything to the left is truncated, consists only of zero here - no problem). But an implied

    MOVE FUNCTION NUMVAL ('07') TO WS-DECIMAL-2.
    

    has to result in zero as it is identical to

    MOVE 00000007.00000 TO WS-DECIMAL-2.
    

    and as WS-DECIMAL-2 only consist of 2 positions to the right of the comma only those (00) are included, the other decimal places (which are one zeros so no problem) and the integer places (which consist of your 07) are truncated.

    For this code to work as "expected" (still with the "assumption" that an alphanumeric storage-area is "considered" to be a valid numeric source) drop the V.

    I suggest to use redefine for this purpose:

           DATA DIVISION.
           WORKING-STORAGE SECTION
           01 WS-VALUE                     PIC 9(15).
           01 WS-VALUE-WITH-2-DECIMAL-POS  REDEFINES WS-VALUE
                                           PIC 9(13)V9(02).
           01 WS-AMOUNT-15                 REDEFINES WS-VALUE
              05 WS-AMOUNT-13              PIC 9(13). 
              05 WS-DECIMAL-2              PIC 9(02).
           
           PROCEDURE DIVISION.
           
           MOVE 000000804793807 TO WS-VALUE
          *> TRY TO DISPLAY THE VALUE.  
           DISPLAY 'AMT(1:13): '    WS-VALUE(1:13). 
           DISPLAY 'AMT(14:2): '    WS-VALUE(14:2).           
           DISPLAY 'WS-AMOUNT-13: ' WS-AMOUNT-13.              
           DISPLAY 'WS-DECIMAL-2: ' WS-DECIMAL-2.              
           DISPLAY 'WS-AMOUNT-15: ' WS-AMOUNT-15.       
    
           GOBACK.