Page 1 of 1

Moving characters to numeric field

PostPosted: Fri Jan 11, 2019 2:22 pm
by HarryBoy
Hi! the below code moves a pic x(35) to a pic 9(12), as I understand the pic x is then converted to pic 9-format when the data is moved.
The moved data consists of a couple of numbers but the last part is a character in this case a "-". But then the "-" should be converted to
a numeric representation, yes?

However as you can see below it checks if the position in the pic 9-parameter is not numeric, but it should be numeric since it was converted and stored in pic 9-parameter?

The code is below:
MOVE WP51I-VALFRI-TEXT(21:12) TO WS-PAYMENT-AMT

EVALUATE TRUE
WHEN WS-PAYMENT-AMT(12:1) IS NUMERIC
SET NUMERIC-FLAG TO TRUE
CONTINUE
WHEN WS-PAYMENT-AMT(12:1) = '-'
MOVE '0' TO WS-PAYMENT-AMT(12:1)



Cheers
Harald

Re: Moving characters to numeric field

PostPosted: Fri Jan 11, 2019 4:23 pm
by NicC
Please look at all the other topics on this subject and read and understand the relevant section of the cobol language reference manual.

Re: Moving characters to numeric field

PostPosted: Fri Jan 11, 2019 5:31 pm
by HarryBoy
Noooo. I want it explained without me having to do anything, served to me on a silver plate! :-) (kidding, I will check the forum posts).

Cheers
Harald

Re: Moving characters to numeric field

PostPosted: Fri Jan 11, 2019 7:48 pm
by Robert Sample
the below code moves a pic x(35) to a pic 9(12), as I understand the pic x is then converted to pic 9-format when the data is moved.
I think you have a DRASTIC misunderstanding about how COBOL works. When you MOVE a PIC X(35) to a PIC 9(12), there is no conversion done -- period. The data is moved (byte by byte) and if the moved data matches the requirements for a zoned decimal number, great -- but if not then you can have non-numeric data in the zoned decimal variable.
but it should be numeric since it was converted and stored in pic 9-parameter?
Since there is no conversion done, your question is nonsensical. To wit:
WORKING-STORAGE SECTION.                        
 01  WS-FILLER.                                  
     05  WS-SOURCE               PIC X(35) VALUE
     'ABCDEFGHIJKLMNOPQRSTUVWXYZ---------'.      
     05  WS-DEST                 PIC 9(12).      
 PROCEDURE DIVISION.                            
      MOVE WS-SOURCE             TO  WS-DEST.    
      DISPLAY 'SOURCE >' WS-SOURCE '<'.          
      DISPLAY 'DEST   >' WS-DEST   '<'.          
      STOP RUN.                                  
produces results of
SOURCE >ABCDEFGHIJKLMNOPQRSTUVWXYZ---------<
DEST   >XYZ--------0<                        
Notice that the ONLY numeric character in the destination is the final zero -- and that is because COBOL forces the final byte of a zoned decimal variable to have a zone when a MOVE to the variable is done (depending upon the compile options, of course). And it is a zero because the EBCDIC collating sequence for a dash is X'60' so COBOL changed the X'60' to X'F0'; if you use something like a period (X'4B') then you would get X'FB' in that final byte.

Re: Moving characters to numeric field

PostPosted: Mon Jan 14, 2019 2:01 pm
by HarryBoy
Hi Robert, thanks for input!

Cheers
Harald

Re: Moving characters to numeric field

PostPosted: Thu May 05, 2022 1:57 am
by WillLamers
Hi Robert -

I think you missed that the OP was not moving all 35 bytes, instead he was moving only 12:

MOVE WP51I-VALFRI-TEXT(21:12) TO WS-PAYMENT-AMT


The subscript (21:12) indicates that 12 bytes will be moved from WP51I-VALFRI-TEXT to WS-PAYMENT-AMT, starting from byte number 21 of the sending field.

I have an issue with using reference modification like this. I am making some assumptions but this is what I would do, using Robert's example. My assumption is that there are valid numeric values in (21:12):


       environment division.
       configuration section.

       data division.
       working-storage section.
       01 WS-FILLER.
         05 WS-SOURCE.
           10 FILLER PIC X(20).
           10 WS-PAYMENT-AMOUNT PIC X(12).
           10 FILLER PIC X(3).
       01 WS-DEST PIC 9(12).

       procedure division.
           MOVE 'ABCDEFGHIJKLMNOPQRST123456789012---'
             TO WS-SOURCE.

           MOVE WS-PAYMENT-AMOUNT TO WS-DEST.
           DISPLAY 'SOURCE >' WS-SOURCE '<'.
           DISPLAY 'DEST   >' WS-DEST '<'.
           STOP RUN.
             
       end program Program1.
 


BTW, here is a link to one of the IBM manuals regarding MOVE: https://www.ibm.com/docs/en/cobol-zos/4.2?topic=statements-move-statement

I've been programming in COBOL since pre-Y2K, and there are still things I need assistance with. Unless you know exactly what you are looking for it may be difficult to find, in this case subscripting the sending field in a MOVE statement.

@HarryBoy, if WP51I-VALFRI-TEXT contains data for more than one field I would create a group with elementals below it, one for each field. If that data is coming in from another process I would also put that code into a copybook which will make maintenance much easier. Take it from someone maintaining a 40+ year old COBOL implementation...

You have probably already solved this issue but I am putting this out to possibly help the next new user.

Finally, I have an issue with those who use the RTFM or RTFF response. It is a Microsoft answer, totally correct but utterly useless...

Cheers,

Will