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.
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.
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.
AS400 RPG Developer - Seeking F/T position
8 个月Had this book in school 1994-1995 Still Have It…
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 :-)
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.