3

I want to use SYNCSORT to force all Packed Decimal fields to a negative sign value. The critical requirement is the 2nd nibble must be Hex 'D'. I have a method that works but it seems much too complex. In keeping with the KISS principle, I'm hoping someone has a better method. Perhaps using a bit mask on the last 4 bits? Here is the code I have come up with. Is there a better way?

*
* This sort logic is intended to force all Packed Decimal amounts to
* have a negative sign with a B'....1101' value (Hex 'xD').
*
 SORT FIELDS=COPY
 OUTFIL FILES=1,
   INCLUDE=(8,1,BI,NE,B'....1..1',OR,     * POSITIVE PACKED DECIMAL
            8,1,BI,EQ,B'....1111'),       * UNSIGNED PACKED DECIMAL
   OUTREC=(1:1,7,                         * INCLUDING +0
           8:(-1,MUL,8,1,PD),PD,LENGTH=1,
           9:9,72)
 OUTFIL FILES=2,
   INCLUDE=(8,1,BI,EQ,B'....1..1',AND,    * NEGATIVE PACKED DECIMAL
            8,1,BI,NE,B'....1111'),       * NOT UNSIGNED PACKED DECIMAL
   OUTREC=(1:1,7,                         * INCLUDING -0
           8:(+1,MUL,8,1,PD),PD,LENGTH=1,
           9:9,72)
Bill Woodger
  • 12,702
  • 4
  • 35
  • 43
MikeC
  • 408
  • 2
  • 4
  • 9
  • By way of explaination - the application I'm working with is using the packed decimal field as a key to a VSAM file. The numerical (absolute) value is guaranteed to be unique. The negative sign is being used to indicate the record needs to be corrected. When the record is updated, the sign is flipped to positive value. In this particular situtation, just prior to loading the vsam file there is a syncsort step. I'm trying to assert that all records passing through the sort have the negative sign set correctly before loading the file. – MikeC Oct 08 '10 at 19:43
  • Maybe try posting this on [MVSForms](http://www.mvsforums.com/helpboards/) under the Utilities topic. The moderator of that form is Frank Yaeger - a senior technical lead at IBM responsible for SYNCSORT as well as a number of other utilities. – NealB Oct 12 '10 at 16:16
  • Thanks for the suggestion. I'll check it out. – MikeC Oct 12 '10 at 23:28
  • Perhaps I should point out the primary issue I have with my solution. The ultimate goal is to sort the data into key sequence (with the negative sign correctly set) and store the results in a VSAM file. With this solution, the data is split into two files and I'm forced to recombine the data with another sort on a 2nd pass. Since the record layout is not changed, I see no need for a 2 pass process. I really want all the output to go to a single file (not two). Am I missing a coding trick here? – MikeC Oct 14 '10 at 21:21
  • NealB, Frank Yaeger was the inventor and chief developer of the modern DFSORT/ICETOOL. SyncSort is a competing product. Frank has retired. MVSForums is run by another DFSORT developer, whose work can be found on other sites as well. – Bill Woodger Jan 30 '13 at 14:57
  • Hi Mike, if you can't recover your original user, you can e-mail support and they can probably help. As to the problem, you have `non-preferred signs. I'll try to check if SyncSORT can deal with that natively, if not, your suggestion of a bit test is going to be the way to go. Interested where your data is coming from. I've been trying to find something which actually produces A, B, E in the sign nybble without success :-) – Bill Woodger Aug 29 '14 at 19:26
  • OK, a neater new version than I was initially expecting. However, there is still that -ve zero from the comments. Do you want zero to be negative (sign-nybble = D) as well? – Bill Woodger Aug 29 '14 at 21:57

4 Answers4

1

Looking at the last byte of a packed field is possible. You want positive/unsigned to negative, so if it is greater than -1, subtract it from zero.

From a short-lived Answer by MikeC, it is now known that the data contains non-preferred signs (that is, it can contain A through F in the low-order half-byte, whereas a preferred sign would be C (positive) or D (negative). F is unsigned, treated as positive.

This is tested with DFSORT. It should work with SyncSORT. Turns out that DFSORT can understand a negative packed-decimal zero, but it will not create a negative packed-decimal zero (it will allow a zoned-decimal negative zero to be created from a negative zero packed-decimal).

The idea is that a non-preferred sign is valid and will be accurately signed for input to a decimal machine instruction, but the result will always be a preferred sign, and will be correct. So by adding zero first, the field gets turned into a preferred sign and then the test for -1 will work as expected. With data in the sign-nybble for packed-decimal fields, SORT has some specific and documented behaviours, which just don't happen to help here.

Since there is only one value to deal with to become the negative zero, X'0C', after the normalisation of signs already done, there is a simple test and replacement with a constant of X'0D' for the negative zero. Since the negative zero will not work, the second test is changed from the original minus one to zero.

With non-preferred signs in the data:

SORT FIELDS=COPY
INREC IFTHEN=(WHEN=INIT,
               OVERLAY=(32:+0,ADD,32,1,PD,TO=PD,LENGTH=1)),
      IFTHEN=(WHEN=(32,1,CH,EQ,X'0C'),
               OVERLAY=(32:X'0D')), 
      IFTHEN=(WHEN=(32,1,PD,GT,0), 
               OVERLAY=(32:+0,SUB,32,1,PD,TO=PD,LENGTH=1))

With preferred signs in the data:

SORT FIELDS=COPY
INREC IFTHEN=(WHEN=(32,1,CH,EQ,X'0C'),
               OVERLAY=(32:X'0D')), 
      IFTHEN=(WHEN=(32,1,PD,GT,0), 
               OVERLAY=(32:+0,SUB,32,1,PD,TO=PD,LENGTH=1))

Note: If non-preferred signs are stuffed through a COBOL program not using compiler option NUMPROC(NOPFD) then results will be "interesting".

Bill Woodger
  • 12,702
  • 4
  • 35
  • 43
  • I would have to retest this again, as it's been well over a year since I came up with the solution I finally implemented. I agree this appears to be a much simpler answer than what I came up with but I seem to think you might run into an issue where the sign nibble is b'....1111'. Again, my memory may be faulty, but during testing I think I came to the conclusion that a '0F'x packed field was treated as an unsigned value - neither positive nor negative which is why it had to be treated as a special case in my example below. – MikeC Jun 12 '13 at 23:30
  • Sorry, I didn't get a notification of your comment. X'0F' is indeed unsigned, but it is greater than -1. I don't *know* for SyncSort, but DFSORT certainly has the concept of -ve zero and would make the zero negative with the above code. If you have "mixed" signs (C/D and F) that is generally a bad idea within one file anyway. To want to change to -ve, your fields must be signed, so there should not really be any Fs in the data. -ve zero can be a pain anyway, but you want everything to be negative... – Bill Woodger Oct 17 '13 at 10:16
1

In the code that processes the VSAM file, can you change the read logic to GET with KEY GTEQ and check for < 0 on the result instead of doing a specific keyed read?

If you did that, you could accept all three negative packed values xA, xB and xD.

Joe Zitzelberger
  • 4,168
  • 1
  • 26
  • 40
  • That's possible but there are multiple programs that would need to be modified and no two programs are alike. The SYNCSORT is the focal point where all the data flows through. It makes sense to apply the change there (if possible). I'll give your answer a vote but it's not my preference. – MikeC Oct 20 '10 at 03:57
1

Have you considered writing an E15 user exit? The E15 user exit lets you manipulate records as they are input to the sort process. In this case you would have a REXX, COBOL or other LE compatible language subroutine patch the packed decimal sign field as it is input to the sort process. No need to split into multiple files to be merged later on.

Here is a link to example JCL for invoking an E15 exit from DFSORT (same JCL for SYNCSORT). Chapter 4 of this reference describes how to develop User Exit routines, again this is a DFSORT manual but I believe SyncSort is fully compatible in this respect. Writing a user exit is no different than writing any other subroutine - get the linkage right and the rest is easy.

This is a very general outline, but I hope it helps.

NealB
  • 15,862
  • 2
  • 34
  • 60
  • I had considered E15 and that might be the best alternative but not as clean-cut as I'd hope. SYNCSORT is what it is. If there are no better suggestions this would be the approach I'd take. – MikeC Oct 20 '10 at 21:52
1

Okay, it took some digging but NEALB's suggestion to seek help on MVSFORUMS.COM paid off... here is the final result. The OUTREC logic used with SORT/MERGE replaces OUTFIL and takes advantage of new capabilities (IFTHEN, WHEN and OVERLAY) in Syncsort 1.3 that I didn't realize existed. It pays to have current documentation available!

*                                                                
* This MERGE logic is intended to assert that the Packed Decimal 
* field has a negative sign with a B'....1101' value (Hex X'.D').
*                                                                
*                                                                
 MERGE FIELDS=(27,5.4,BI,A),EQUALS                               
 SUM FIELDS=NONE                                                 
 OUTREC IFTHEN=(WHEN=(32,1,BI,NE,B'....1..1',OR,                 
                      32,1,BI,EQ,B'....1111'),                   
                OVERLAY=(32:(-1,MUL,32,1,PD),PD,LENGTH=1)),      
        IFTHEN=(WHEN=(32,1,BI,EQ,B'....1..1',AND,                
                      32,1,BI,NE,B'....1111'),                   
                OVERLAY=(32:(+1,MUL,32,1,PD),PD,LENGTH=1))  
MikeC
  • 408
  • 2
  • 4
  • 9