Add it Up in RPG

Add it Up in RPG

One of the features that has been re-introduced to RPG over the decades is the myriad methods to perform an ADD operation. I recently had to go back and open one of the first edition copies of "The Modern RPG Language" I have in my library to read up on the original fixed-format ADD opcode. Sadly it didn't have information on what happens when the ADD causes an overflow of the target variable.

As year-end processing rolls upon us this week, I usually end up getting a call about what I like to label: high-order truncation occurred. I get that term from my college days in the Computer lab compiling COBOL which I keypunched onto 80-column cards. If a target numeric value was smaller in length than the value being added to it, you would get a compile-time message "High-order Truncation may occur". That was such an unfamiliar term to me and I had to research what it meant.

If you're performing arithmetic operations and the result exceeds the defined size of the target field, the warning indicates that the result may lose digits from the leftmost (high-order) side, potentially leading to inaccuracies in your computations.

When I started programming in RPGII (System/34) later on, I never had that issue. Then in RPG III (System/38) it too never came up. By the time RPG IV came around I had forgotten about the COBOL warning until we started talking about the pre-Free-format RPGIV which we called the "extended factor 2" or sometimes "hybrid RPG". That version introduced the EVAL opcode. So instead of the RPGII/RPGIII style of:

     C                   ADD       10            P72        

The EVAL code supported expressions:

     C                   EVAL      P72 += 10        

Later on when totally free format RPG came around, the only real difference is the starting point for the EVAL opcode and the fact that you no longer need to specify the EVAL opcode itself (it is implied):

 P72  += 10;          

Numeric Overflow / High-Order Truncation

The fixed-format ADD opcode and the free-format EVAL opcode handle math differently. So legacy RPG using the ADD opcode that is then converted to free format without any context, could blow up.

Why? Because the ADD opcode did not care if High-Order Truncation occurred. It simply truncated the high-order portions of the number to fit into the target value. So those Packed(7, 2) values once they reached 99999.99 the next ADD opcode would roll it over. Here's an example:

        dcl-s P72  Packed(7 : 2) INZ(99999.99);
       
     C                   ADD       10            P72              

After this ADD opcode is run, the value for P72 = 10.99. The ADD produced a result of 100010.99 and since that value cannot fit into P72, it simply truncated the result to 10.99 -- no error, no message, just good old bad data. The program continues as if nothing happened.

Now let's do the same thing using a free-format EVAL expression:

       dcl-s P72  Packed(7 : 2) INZ(99999.99)
      
       P72  += 10;        

Bam! MCH1210 - "Receiver value too small to hold result".

This is how it should be in programs. So the EVAL is working as designed.

You can trap these overflow errors using the awesome MONITOR/ON-ERROR opcodes.

        dcl-s P72  Packed(7 : 2) INZ(99999.99)
        monitor;
          P72  += 10;
        on-error;
        // Do your exception/error handling here
          p72 = 0;
        endmon;        

If you're using SQL, the same kind of thing will happen--the overflow will signal an error--you can also use MONITOR/ON-ERROR to trap those errors as well, as follows:

      dcl-s P72  Packed(7 : 2) INZ(99999.99)
      monitor;
      EXEC SQL Values :p72 + 10 INTO :P72;
      on-error;
        // Do your exception/error handling here
      endmon;          

Be aware that in some rare situations, moving to free format may not work identical to the fixed format version. In the vast majority of cases, they free-format and fixed-format versions of opcodes perform exactly the same, just make sure you math works.

That's all there is to it.


John Knox

IBM i, iSeries, AS/400 System Administrator available for new opportunities

8 个月

That looks just like the B30 I first worked on, with that "wonderful" reel tape drive. Many hours spent doing OS upgrades loading multiple tapes, hoping and praying you didn't get a media error. For the curious ones (like me) who thought those white racks were a lot taller back then. I just looked and IBM specs say a 9309 rack is 62.1 inches tall. Based on that, I'm guessing Bob is around 6 feet tall.

回复
Steven Goldman

Sr Engineer Specialist - FedEx Ground PTC Implementer Administrator

8 个月

Hi Bob, I had this happen to me. I was working on a pension system, and we had an employee who was in the C-Suite. His check was supposed to be 1.8 million, but he only got 800,000.00 on the actual check. It was a big issue, what I did to solve it was manually change the ACH file that was sent to the bank. We did not fix the code as the system was going from Cyborg payroll to SAP.

回复
Rick Briggs

AS400 RPG Developer - Seeking F/T position

8 个月

Had this book in school 1994-1995 Still Have It…

回复
Jeff Silberberg

Partner DAPage, LLC & Owner, CompuDesigns, Inc.

8 个月

Hey Bob, with the exception of the 8" diskette drive, it looks like a twin to the B35 I had for five years. Before the lease ended and it became a 170. My wife said the temp in the house went up 5 degrees when I was running it :-)

Rob Berendt

System Analyst/Security at Group Dekko, #IBMChampion

8 个月

That EPO (Emergency Power Off) switch was intended to be a one use only. Found that out when I used it upon powering the machine off to get it out of the building and out of service. Either that, or it was the same faulty plastic used in many of IBM's twinax terminals. I had to get a lot of those switches replaced. Never heard about it from the trade in company and I didn't ask.

要查看或添加评论,请登录

社区洞察

其他会员也浏览了