Old Programs Can Learn to Behave Themselves
May 16, 2007 Ted Holt
As far as I know, nothing disastrous has ever come of a truncation error in one of my programs. Nevertheless, I’m embarrassed when someone points out that a total figure does not equal the sum of the column of numbers above it. RPG’s EVAL opcode generates a hard error if high-order numeric truncation occurs. We can use the MONITOR opcode to trap EVAL’s truncation errors. But what about all those programs that use antique op codes like ADD, SUB, MULT, and DIV?
You can easily make those op codes raise errors upon truncation. Let’s see how it’s done. Here’s an extremely sophisticated program that generates a truncation error.
C move *on *inlr C z-add 995 SomeNumber 3 0 C add 10 SomeNumber C return
The final value of SomeNumber is five, of course. The program continues along without the slightest concern that 1000 of something has been obliterated.
The solution is to add the TRUNCNBR keyword with a value of *NO to the H specs.
H truncnbr(*no) C move *on *inlr C z-add 995 SomeNumber 3 0 C monitor C add 10 SomeNumber C on-error C move *hival SomeNumber C endmon C return
Without the MONITOR, the ADD operation generates messages MCH1210 (Receiver value too small to hold result) and RNQ0103. (The target for a numeric operation is too small to hold the result C G D F.)
I wouldn’t advise anyone to automatically add this keyword to all the old programs in their shop, because too many programs depend on truncation. A good example is the use of constants like 100.0001 to convert dates from one format to another. For those of you who don’t know this trick, multiplying a six-digit number by 100.0001 and storing the result in a six-digit number converts YYMMDD to MMDDYY. Also, multiplying a six-digit number by 10000.01 converts MMDDYY to YYMMDD. Now that you know this trick, don’t use it.