Tuesday, December 6, 2011

SORT : Reformatting packed decimal

Assume that I have a file with the record, name and amount alone.
Name with X(10) and Amount of S9(7)V9(2) COMP-3.

I would want to sort this. But in my output file, the amount field is to be increased to S9(7)V9(3) COMP-3.

How is it possible to get the same values with an additional digit after the decimal point ?


To make it a little clearer, this is what  wanted:

Input

TMP-NAME   TMP-AMOUNT
10/AN      5/PS      
(1-10)     (11-15)  
1--------- 2----------
**********************
RAVI            100.00
TEST        1234567.89
TEST MINUS -1234567.89
**********************



Output

TMP-NAME   TMP-AMOUNT
10/AN      6/PS      
(1-10)     (11-16)    
1--------- 2-----------
***********************
RAVI            100.000
TEST        1234567.890
TEST MINUS -1234567.890



Here is the easiest way  

//STEP010 EXEC PGM=SORT                                            
//SYSOUT    DD SYSOUT=*                                            
//SYSUDUMP  DD SYSOUT=*                                            
//SORTIN    DD DISP=SHR,DSN=USERID.TSTS.INPUT
//SORTOUT   DD DSN=USERID.TSTS.OUTPUT,                          
//          DISP=(NEW,CATLG,DELETE),SPACE=(TRK,(1,1))              
/*                                                                 
//SYSIN DD *                                                       
 SORT FIELDS=COPY                                                 
 INREC FIELDS=(1,10,                 * KEEP THE FIRST 10 BYTES 
        +10,MUL,11,5,PD,PD,LENGTH=6) * MULTIPLY NEXT 5 BYTES BY 10          
/*                                                                 



At least some of you must be wondering how the solution proposed above works. If we multiply +123.45 by 10, how do we get +123.450? Won't we get +1230.45 ?

  This is just for the sake of those who thought in those lines...

  Well, the trick lies in the way data is stored internally. As you know, the decimal point (i.e. the "V" in S9(07)V99 COMP-3) is not stored at all. Hence, SORT does not see the value of +123.45, but just +12345 (internally X'000012345C' for S9(07)V99 COMP-3). Now, when we multiply this by 10, SORT gives us +123450 (internally X'00000123450C'), which if seen through a field structure of S9(07)V999 COMP-3 will give us the value of +123.450. 

   (Don't let the "C" or "D" confuse you. It is just the sign nibble stored as the least significant 4 bits - "C" indicates it is positive and "D" negative. Just ignore this nibble while looking at the internal representation, and it will be a lot clearer.)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.