RPG Academy: BIF Up Your Code! Start Moving MOVE and MOVEL out of Your Code

RPG
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

 

The MOVE and MOVEL op codes are workhorses in fixed-format RPG, but they don't exist in free-format. Use the EVAL op code and a few BIFs to remove MOVE and MOVEL!

 

There are many uses for the MOVE and MOVEL operation codes: initializing (or even declaring) variables, moving values from one variable to another (which sometimes implies a conversion between data typescharacter to numeric or vice versa, for example), truncating a numeric value, copying part of a string to a different string variable, and so on. Providing you with the tools to totally remove MOVE from your code is a considerable task, and I'll try to address it in this and the following TechTips, thus paving the way to a migration to free-format (that too will be the subject of a few TechTips later in this series).

 

Removing MOVE from Your Numeric Conversion Operations

This time, I'll focus on the conversion to numeric data types. Take the example below:

 

D REGION          S              2A   Inz('12')
D REGCOD         S             2P 0 Inz(*ZEROS)

(…)


C                   MOVEL     REGION        REGCOD

 

This is a fairly common use of MOVE: moving a character value into a decimal variable, implicitly forcing a data-type conversion from character to decimal. This works, no question about that. The problem is that the readability is not the best because the MOVEL operation hides the data types involved and might, in some cases, cause unexpected and (more importantly) undetected errors. By using EVAL and the %DEC BIF, as shown below, you can achieve the same result, in a more readable manner that simultaneously prepares the code for a smooth free-format conversion:

 

C                   EVAL     REGCOD = %DEC(REGION)

 

You can add a MONITOR block around the EVAL to check for errors. I won't go into details about that now, but I promise I'll explain it in a future TechTip. Anyway, back to the matter at hand: %DEC can be used with additional parameters that define the precision and number of decimal places used for the conversion operation. These two parameters are optional. There's also another BIF, similar to %DEC, that automatically performs half-adjust; it's %DECH. However, this BIF requires all three parameters (numeric or character expression to convert, precision, and decimal places) to be specified. To help you understand the use of these BIFs and their parameters, here's an example adapted from IBM's ILE RPG Reference Manual:

 

D p7             s             7p 3 inz (1234.567)

D s9             s             9s 5 inz (73.73442)

D f8             s             8f   inz (123.456789)

D c15a           s             15a   inz (' 123.456789 -')

D c15b           s            15a   inz (' + 9 , 8 7 6 ')

D result1         s             15p 5

D result2         s             15p 5

D result3         s             15p 5

 

 

* using numeric parameters    

C                   EVAL     result1 = %DEC(p7) + 0.011

* "result1" is now 1234.57800

C                   EVAL    result2 = %DEC(s9 : 5: 0)

* "result2" is now   73.00000

C                   EVAL    result3 = %DECH(f8: 5: 2)

* "result3" is now 123.46000

 

* using character parameters

C                   EVAL    result1 = %DEC(c15a: 5: 2)

* "result1" is now -123.45

C                   EVAL    result2 = %DECH(c15b: 5: 2)

* "result2" is now 9.88000

 

Have you noticed how the precision parameter in the second and third EVAL operations influences the final result? It's also important to mention that plus sign (+) or minus sign (-) characters will be used when converting a character string to a decimal value, as shown in the fourth EVAL operation. Please read the chapter on Conversion Operations in the ILE RPG Reference Manual for more details.

 

Need to Convert Something to Integer? Here's a (h)%int

What if the target data type was an integer or a float? Well, there are also BIFs for that: %INT and %FLOAT, respectively. Let's start with %INT: it has only one parameterthe character or numeric expression to be converted to integerand it simply drops the decimal places when performing the conversion. In other words, 123.456 will be converted to 123. If you need to take into account the decimal part, performing the half-adjust, then you should use %INTH. It's similar to %INT in every way, except for the half-adjust operation. Here's an example adapted from IBM's ILE RPG Reference Manual:

 
D p7             s             7p 3 inz (1234.567)
D s9             s             9s 5 inz (73.73442)
D f8             s             8f   inz (123.789)
D c15a           s             15a   inz (' 12345.6789 -') 
D c15b           s             15a   inz (' + 9 8 7 . 6 5 4 ') 
D result1         s             15p 5
D result2         s             15p 5
D result3         s             15p 5
 
* using numeric parameters     

C                   EVAL    result1 = %INT(p7) + 0.011

 
 * "result1" is now 1234.01100.
C                   EVAL   result2 = %INT(s9)
 * "result2" is now   73.00000
C                   EVAL    result3 = %INTH(f8)
 * "result3" is now 124.00000.
 
 * using character parameters 
C                   EVAL    result1 = %INT(c15a)
 * "result1" is now -12345.00000 
C                   EVAL    result2 = %INTH(c15b)
 * "result2" is now 988.00000 

 

The second and third EVAL operations show the difference between %INT and %INTH: if the example used %INT instead of %INTH in the third EVAL operation, the result3 variable would contain 123.0000 instead of 124.00000.

 

Whatever %FLOAT(s) Your Boat

Finally, a quick word about %FLOAT: it works just like %INT, and it converts the numeric or character expression to float. If the value to convert is a character expression, the following rules apply:

  • The sign is optional. It can be a plus sign (+) or a minus sign (-), but it must precede the numeric data.
  • The decimal point is optional, and you can use either a period or a comma.
  • If invalid numeric data is found, an exception occurs with status code 105.
  • The exponent is optional. It can be either E or e. The sign for the exponent is optional, and it must precede the numeric part of the exponent.
  • Blanks are allowed anywhere in the data. For example, + 3 , 5 E 9 is a valid parameter.

 

The first three rules are also applicable to %INT and %INTH. Just to consolidate all this information, here's an example adapted from IBM's ILE RPG Reference Manual:

 

D p1             s             15p 0 inz (1)
D p2              s             25p13 inz (3)
D c15a           s             15a   inz('-5.2e-1')
D c15b           s             15a   inz(' + 5 . 2 ')
D result1         s             15p 5
D result2         s             15p 5
D result3         s             15p 5
D result4         s             8f
 
 * using numeric parameters
C                   EVAL    result1 = p1 / p2
 * "result1" is now 0.33000.
C                   EVAL    result2 = %float (p1) / p2
 * "result2" is now 0.33333.
C                   EVAL    result3 = %float (p1 / p2)
 * "result3" is now 0.33333.
C                   EVAL    result4 = %float (12345)
 * "result4" is now 1.2345E4 
 
 * using character parameters 
C                   EVAL    result1 = %float (c15a)
 * "result1" is now -0.52000.
C                   EVAL    result2 = %float (c15b)
 * "result2" is now 5.20000.
C                   EVAL    result4 = %float (c15b)
 * "result4" is now 5.2E0

 

A Word About Fixed-Format Code

All the examples of this and the next TechTips were "downgraded" from free-format to fixed-format to keep the readers unfamiliar with "modern" RPG in the loop. But don't get me wrong: I don't advise writing new code in fixed-format! However, migrating to free-format can be a somewhat complicated process (especially inside our heads), and I'll get to that after preparing the ground with a few more tips that (I hope) will help you make a smoother transition from "old" to "modern" RPG.

 

The next TechTip will continue on this path, covering a few string-related BIFs as well as the conversion from numeric to character data types, which is another big use of MOVE and MOVEL. I want to hear from you: reader feedback is very important for writers! Comment, argue, agree, or disagreejust speak your mind in the Comments section below!

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$0.00 Raised:
$